Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Error reading two dates from a binary file

Tags:

date

c#

When reading two dates from a binary file I'm seeing the error below:

"The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'. Parameter name: chars"

My code is below:

static DateTime[] ReadDates()
{
    System.IO.FileStream appData = new System.IO.FileStream(
       appDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read);

    List<DateTime> result = new List<DateTime>();
    using (System.IO.BinaryReader br = new System.IO.BinaryReader(appData))
    {
        while (br.PeekChar() > 0)
        {
            result.Add(new DateTime(br.ReadInt64()));
        }
        br.Close();
    }
    return result.ToArray();
}

static void WriteDates(IEnumerable<DateTime> dates)
{
    System.IO.FileStream appData = new System.IO.FileStream(
       appDataFile, System.IO.FileMode.Create, System.IO.FileAccess.Write);

    List<DateTime> result = new List<DateTime>();
    using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(appData))
    {
        foreach (DateTime date in dates)
            bw.Write(date.Ticks);
        bw.Close();
    }
}

What could be the cause? Thanks

like image 829
Jamie Avatar asked Jul 22 '26 11:07

Jamie


2 Answers

The problem is that you're using PeekChar - that's trying to decode binary data as if it were a UTF-8 character. Unfortunately, I can't see anything else in BinaryReader which allows you to detect the end of the stream.

You could just keep calling ReadInt64 until it throws an EndOfStreamException, but that's pretty horrible. Hmm. You could call ReadBytes(8) and then BitConverter.ToInt64 - that would allow you to stop when ReadBytes returns a byte array with anything less than 8 bytes... it's not great though.

By the way, you don't need to call Close explicitly as you're already using a using statement. (That goes for both the reader and the writer.)

like image 72
Jon Skeet Avatar answered Jul 24 '26 01:07

Jon Skeet


I think Jon is correct that it's PeekChar that chokes on the binary data.

Instead of streaming the data, you could get it all as an array and get the values from that:

static DateTime[] ReadDates() {
  List<DateTime> result = new List<DateTime>();
  byte[] data = File.ReadAllBytes(appDataFile);
  for (int i = 0; i < data.Length; i += 8) {
    result.Add(new DateTime(BitConverter.ToInt64(data, i)));
  }
  return result;
}
like image 41
Guffa Avatar answered Jul 23 '26 23:07

Guffa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!