Reputation: 419
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;
}
Upvotes: 1
Views: 456
Reputation: 726987
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();
Upvotes: 1