1

I have a simple procedure to write a list of library books (of type TBook) to a binary file as follows:

static void SaveToFile(List<TBook> lib)
    {
        FileStream currentFile;
        BinaryWriter writerToFile;
        currentFile = new FileStream("MyLibrary.bin", FileMode.Create);
        writerToFile = new BinaryWriter(currentFile);
        foreach (TBook book in lib)
        {
            writerToFile.Write(book.Title);
            writerToFile.Write(book.Author);
            writerToFile.Write(book.Genre);
            writerToFile.Write(book.BookID);
        }
        writerToFile.Close();
        currentFile.Close();
    }

However, when trying to read the binary file and load contents into a list, i get an error:

An unhandled exception of type 'System.IO.EndOfStreamException' occurred in mscorlib.dll

Additional information: Unable to read beyond the end of the stream.

Here is my subroutine that attempts to read the Binary File back into a Struct again:

static List<TBook> LoadDataFromFile (List<TBook>library)
    {
        FileStream currentFile;
        BinaryReader readerFromFile;
        currentFile = new FileStream("MyLibrary.bin", FileMode.Open);
        readerFromFile= new BinaryReader(currentFile);

        while (currentFile.Position < currentFile.Length)
        {
            TBook CurrentRecord = new TBook();
            CurrentRecord.Title = readerFromFile.ReadString();
            CurrentRecord.Author = readerFromFile.ReadString();
            CurrentRecord.Genre = readerFromFile.ReadString();
            CurrentRecord.BookID = readerFromFile.ReadInt16();
            library.Add(CurrentRecord);                
       }

        readerFromFile.Close();
        currentFile.Close();
        return library;
    }

I assume the issue is with the line:

while (currentFile.Position < currentFile.Length) 

Note: The Struct is setup as follows:

struct TBook
    {
        public string Title;
        public string Author;
        public string Genre;
        public int BookID;
    }
3
  • 1
    This is not a good way to serialize your data to files. If you still want to use the binary format, you should (de)serialize the whole object graph using BinaryFormatter and not process each property manually. BTW, don't use structs. Commented Dec 13, 2018 at 17:01
  • 2
    The issue is with ID. You are writing an integer but reading a short. Commented Dec 13, 2018 at 17:05
  • The smells like homework, since a Serializer would do the job so much better Commented Dec 13, 2018 at 19:22

1 Answer 1

1

When you are serializing data as binary, your deserialization code must follow serialization code exactly; otherwise your deserializer starts reading junk from adjacent positions, eventually causing an exception or silently populating your structures with wrong data.

This pair of calls is mismatched:

writerToFile.Write(book.BookID);
....
CurrentRecord.BookID = readerFromFile.ReadInt16();

It is hard to see this problem, because BinaryWriter overloads the Write method. Since book.BookID is of type int, an alias for Int32, the call to Write is resolved to Write(Int32). Therefore, the corresponding read must also read Int32, not Int16:

CurrentRecord.BookID = readerFromFile.ReadInt32();
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.