开发者

C# Error reading two dates from a binary file

开发者 https://www.devze.com 2022-12-31 16:09 出处:网络
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.Dec

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(
     开发者_如何学C  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


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.)


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;
}


A simple solution to your problem would be to explicitly specify ASCII encoding for the BinaryReader, that way PeekChar() uses only a single byte and this kind of exception (a .NET bug, actually) doesn't happen:

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

精彩评论

暂无评论...
验证码 换一张
取 消