从二进制文件中读取两个日期时,我看到以下错误:
“输出字符缓冲区太小,无法包含已解码的字符,编码'Unicode(UTF-8)'后备'System.Text.DecoderReplacementFallback'。参数名称:字符”
我的代码如下:
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();
}
}
可能是什么原因?感谢
答案 0 :(得分:4)
问题是您正在使用PeekChar
- 它正在尝试解码二进制数据,就像它是UTF-8字符一样。不幸的是,我在BinaryReader
中看不到任何可以检测到流结束的其他内容。
你可以继续调用ReadInt64
,直到它抛出EndOfStreamException
,但这太可怕了。嗯。您可以调用ReadBytes(8)
然后调用BitConverter.ToInt64
- 这将允许您在ReadBytes
返回任何小于8字节的字节数组时停止...但它不是很好。
顺便说一下,由于您已经使用Close
语句,因此无需明确调用using
。 (这适用于读者和作者。)
答案 1 :(得分:1)
我认为Jon是正确的,它是PeekChar
扼杀二进制数据。
您可以将所有数据作为数组获取,而不是流式传输数据,并从中获取值:
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;
}
答案 2 :(得分:0)
答案 3 :(得分:0)
对您的问题的一个简单解决方案是明确指定BinaryReader
的ASCII编码,这种方式PeekChar()
只使用一个字节,这种异常(实际上是一个.NET错误)不会发生了:
using (System.IO.BinaryReader br = new System.IO.BinaryReader(appData, Encoding.ASCII))