0

I am wondering if it's a good practice to use the EndOfStreamException to detect the end of the BinaryReader stream> I don't want to use BaseStream.Length property or PeekChar as proposed here

C# checking for binary reader end of file

because I have to load it into memory (maybe because it's from Zip file) and enable some flags. Instead, this is what I'm doing:

using (ZipArchive zipArchive = ZipFile.OpenRead(Filename))
  using (BinaryReader fStream = new BinaryReader(zipArchive.Entries[0].Open()))
  {
    while(true){
    try
    {
      fStream.ReadInt32();
    }
    catch (EndOfStreamException ex)
    {
      Log.Debug("End of Binary Stream");
      break;
    }
}

}

Elias Ghali
  • 823
  • 1
  • 13
  • 29

3 Answers3

2

That approach is fine. If you know you have a seekable stream you can compare its length to the number of bytes read. Note that FileStream.Length does not load the whole stream into memory.

But that approach is appropriate for arbitrary streams.

And don't worry about the cost of using exceptions in this case, as streams imply IO, and IO is orders of magnitude slower that exception handling.

David Browne - Microsoft
  • 80,331
  • 6
  • 39
  • 67
  • 1
    yes the problem is that the stream is not seekable I think because it's reading from Zip file: using (ZipArchive zipArchive = ZipFile.OpenRead(Filename)) { using (BinaryReader fStream = new BinaryReader(zipArchive.Entries[0].Open())) , if I try to access BaseStream.Length property it throws NotSupportedException, https://stackoverflow.com/a/3373614/4358873 so in this case I think it's ok to rely on the exception – Elias Ghali Mar 23 '22 at 14:06
1

I would argue that 'best practice' is to have the number of values known, for example by prefixing the stream with the number of values. This should allow you to write it like

var length = fStream.ReadInt32();
for(var i = 0; i < length-1; i++){
    fStream.ReadInt32(); // Skip all values except last
}
return fStream.ReadInt32(); // Last value

First of all this would reduce the need of exception handling, if you reach the endOfStream before the last item you know the stream was incorrectly saved, and have a chance of handling it, instead of just returning the last available value. I also find it helpful to have as few exceptions as possible, so you can run your debugger with "break with thrown", and have some sort of confidence that thrown exceptions indicate actual problems. It can also allow you to save your values as part of some other data.

If you cannot change the input format you can still get the uncompressed length of the entry from ZipArchiveEntry.Length. Just divide by sizeof(int) to get the number of values.

In most cases I would also argue for using a serialization library to save data. This tend to make it much easier to change the format of the data in the future.

JonasH
  • 28,608
  • 2
  • 10
  • 23
  • However, I don't have control of the input stream, The reader gets the ZIP input and should read it – Elias Ghali Mar 23 '22 at 15:27
  • @Elias Ghali If there is no way to find out the number of values I would argue whoever saved the data did not follow 'best practice'. But you can check the stream length from the zip-entry to workaround the problem. – JonasH Mar 23 '22 at 15:32
  • Yes this definitly would be a solution also, but the problem is that it's not always int. the file is split, first I read Bytes, then read Int32. However thanks for the tip – Elias Ghali Mar 23 '22 at 15:37
  • @Elias Ghali So, how do you know how many bytes to read? If the format is not self-describing you need an separate layout defining what each byte means. – JonasH Mar 23 '22 at 15:39
  • I rely on certain characters like breakline – Elias Ghali Mar 23 '22 at 18:28
-1

check your program or init value.

GOGO DIDN
  • 24
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 24 '22 at 00:32