8

Is anyone familiar with a way to find out you're at the end of the file? I'm using BinaryReader and tried PeekChar - but it throws an exception. Any other suggestions?

Thanks.

eve
  • 81
  • 1
  • 1
  • 2

5 Answers5

11

From a Stream, if you Read(buffer, offset, count) you'll get a non-positive result, and if you Peek() you'll get a negative result.

With a BinaryReader, the documentation suggests that PeekChar() should return negative:

Return Value

Type: System.Int32 The next available character, or -1 if no more characters are available or the stream does not support seeking.

are you sure this isn't a corrupt stream? i.e. the remaining data cannot form a complete char from the given encoding?

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    I've done while (binReader.PeekChar() ! = -1 ) {...} This is what I get: The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'. Parameter name: chars – eve Feb 16 '11 at 12:46
  • @MarcGravell There is probably a bug/feature somewhere in the `DecoderReplacementFallback` so that `new BinaryReader(new MemoryStream(new byte[] { 194, 0, 0 })).PeekChar()` will throw an exception (not all the illegal sequences of three bytes will throw... For example `{ 192, 0, 0 }` won't – xanatos Apr 04 '17 at 12:38
2

If your stream supports seeking (check this using the BaseStream.CanSeek property), check the Position property of the BaseStream, like so:

if (myBinaryReader.BaseStream.CanSeek){
   bool atEnd = (myBinaryReader.BaseStream.Position == myBinaryReader.BaseStream.Length - 1)
}
WiseGuyEh
  • 18,584
  • 1
  • 20
  • 20
1

Checking whether the position of the reader is less than its length does the trick

While BinReader.Position < BinReader.Length
{
 ... BinReader.Read() ...
}
Nepaluz
  • 669
  • 1
  • 12
  • 27
  • Using `Stream.Position` or `Stream.Length` will cause an exception if `CanSeek == false`. – Dai Oct 21 '20 at 08:57
0

I'll add my suggestion: if you don't need the "encoding" part of the BinaryReader (so you don't use the various ReadChar/ReadChars/ReadString) then you can use an encoder that won't ever throw and that is always one-byte-per-char. Encoding.GetEncoding("iso-8859-1") is perfect for this. The iso-8859-1 encoding is a one-byte-per-character encoding that maps 1:1 all the first 256 characters of Unicode (so the byte 254 is the char 254 for example)

xanatos
  • 109,618
  • 12
  • 197
  • 280
-2
While BinReader.PeekChar() > 0
{
...
}
Jaime Oro
  • 9,899
  • 8
  • 31
  • 39