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))
精彩评论