BinaryReader.PeekChar() throws Conversion Buffer Overflow exception
Hi There,
I'm reading in a binary data file with a BinaryReader and it's throwing an exception with some of the data. Here's a simplified read loop:
while (r.PeekChar() > -1)
{
double input = r.ReadDouble();
Console.WriteLine(input);
}
And here's the exception it throws:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Conversion buffer overflow.
As far as I know this is the correct way to read in the file, because I want to stop when I get to the end and don't want to be throwing end of file exceptions.
My best guess at what's happening is that the binary file is a file of doubles (64 bits), the peakChar function reads in an char/int (32 bits) and so some of the numbers get too big, overflow the buffer, and throw an exception. That's the only thing I could think of, maybe I'm off the mark, but otherwise it should work fine. It works fine for the first 900 values or so and then for some points in the file after that it starts throwing the exception. The file contains ~250,000 data points. There's a big long list of function calls, it starts in PeekChar and ends up down in System.Text.UTF8Encoding.GetChars(), I can email a screenshot of the error if necessary. I can also send my data file if need be. Any ideas?
Thanks for any help,
Chris
Hello Chris,
It looks like you have correctly diagnosed your problem (32 bit <-> 64 bit).
Rather than calling PeekChar, I would recommend one of the following:
- calling ReadDouble only and doing the proper bounds check before you start looping; using BaseStream.Length (assuming the stream length is fixed while reading).
- calling ReadBytes instead of PeekChar/ReadDouble and then using the Conversion routines to convert those bytes into a Double. This solution has the advantage of supporting streams that are being updated while you are reading. Calling ReadBytes may return less than the 64-bits you request, in which case you can handle as you see fit.
Please feel free to post back to this thread if you have further technical details or find a solution to your issue.
Hope that helps,
Stephen
http://blogs.msdn.com/stfisher
Hi Stephen,
Thanks for the help. Just a couple questions because I'm not that familiar with .NET yet.
So the steps I'd be doing (for your second option) are to declare a byte array:
// array of 8 bytes, since doubles are 8 bytes long?
byte[] byteData = new byte
Use the ReadBytes method
byteData = tagBinaryReader.ReadBytes(8);
Then I'm using conversion routines, so I'm using something like Convert.ToDouble(byte), this only converts one byte a time, it won't handle an array of bytes, is there another function that will? Or do I have to build up the double by multiplying each of the 8 bytes by the right factor (to get it in the right bit position, eg. *2^8)? Do you have a quick example of this you can show me because I'm not too good at this sort of thing.
Also this needs to be wrapped in a loop so that I stop at the end of file, what's ReadBytes() going to return when it hits the end of a file? -1? I don't want it to just throw an exception. Can you give a quick example of a loop?
Thanks a lot for the help,
Chris