C # Error reading two dates from binary

When reading two dates from a binary file, I see the error below:

"The char output buffer is too small to contain 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 reason? Thanks to

+2


a source to share


4 answers


The problem is what you are using PeekChar

- trying to decode binary data as if it was a UTF-8 character. Unfortunately, I don't see anything in BinaryReader

that allows you to detect the end of the stream.

You can just call ReadInt64

until he kicks out EndOfStreamException

, but that's pretty awful. Hmm. You can call ReadBytes(8)

and then BitConverter.ToInt64

- this will allow you to stop when it ReadBytes

returns a byte array with anything less than 8 bytes ... this is not very good.



By the way, you don't need to call explicitly Close

since you are already using the operator using

. (This applies to both the reader and the writer.)

+4


a source


I think John is right that he PeekChar

is choking on binary data.

Instead of streaming data, you can get the whole thing as an array and get 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;
}

      

+1


a source


0


a source


A simple solution to your problem would be to explicitly specify the ASCII encoding for BinaryReader

, so PeekChar()

only uses one byte, and this kind of exception (actually, a .NET error) does not happen:

using (System.IO.BinaryReader br = new System.IO.BinaryReader(appData, Encoding.ASCII))

      

0


a source







All Articles