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
a source to share
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.)
a source to share
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;
}
a source to share
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))
a source to share