Чтение данных двоичного файла в список структур - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть простая процедура, чтобы записать список библиотечных книг (типа TBook) в двоичный файл следующим образом:

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();
    }

Однако при попытке прочитать двоичный файл и загрузить содержимое всписок, я получаю сообщение об ошибке:

Произошло необработанное исключение типа 'System.IO.EndOfStreamException' в mscorlib.dll

Дополнительная информация: невозможно прочитать после окончанияstream.

Вот моя подпрограмма, которая пытается снова прочитать двоичный файл обратно в Struct:

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;
    }

Я предполагаю, что проблема связана со строкой:

while (currentFile.Position < currentFile.Length) 

Примечание. Структура настроена следующим образом:

struct TBook
    {
        public string Title;
        public string Author;
        public string Genre;
        public int BookID;
    }

1 Ответ

0 голосов
/ 13 декабря 2018

Когда вы сериализуете данные в двоичном виде, ваш код десериализации должен точно соответствовать коду сериализации;в противном случае ваш десериализатор начинает считывать ненужную информацию из соседних позиций, что в конечном итоге вызывает исключение или незаметно заполняет ваши структуры неверными данными.

Эта пара вызовов не соответствует:

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

Трудно увидетьэта проблема, потому что BinaryWriter перегружает метод Write.Поскольку book.BookID имеет тип int, псевдоним для Int32, вызов Write разрешается до Write(Int32).Следовательно, соответствующее прочтение должно также читать Int32, а не Int16:

CurrentRecord.BookID = readerFromFile.ReadInt32();
...