бинарный писатель не открывает файл в конце потока - PullRequest
0 голосов
/ 22 июля 2010

У меня есть метод, который использует бинарный пишущий для записи записи, состоящей из нескольких uints и байтового массива в файл.Этот метод выполняется около десятка раз в секунду как часть моей программы.Код ниже:

iLogFileMutex.WaitOne();
using (BinaryWriter iBinaryWriter = new BinaryWriter(File.Open(iMainLogFilename, FileMode.OpenOrCreate, FileAccess.Write)))
{
    iBinaryWriter.Seek(0, SeekOrigin.End);
    foreach (ViewerRecord vR in aViewerRecords)
    {
        iBinaryWriter.Write(vR.Id);
        iBinaryWriter.Write(vR.Timestamp);
        iBinaryWriter.Write(vR.PayloadLength);
        iBinaryWriter.Write(vR.Payload);        
    }
}    
iLogFileMutex.ReleaseMutex();

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

Поэтому мой вопрос: почемуt C # гарантирует, что текущая позиция находится в конце, когда я открываю файл?

PS: я исключил проблемы с многопоточностью из-за этой ошибки

Ответы [ 2 ]

4 голосов
/ 22 июля 2010

Если вы хотите добавить файл, вы должны использовать FileMode.Append в вашем вызове Open, в противном случае файл откроется с его позицией, установленной в начало файла, а не в конец.

1 голос
/ 22 июля 2010

Проблема заключается в сочетании FileMode.OpenOrCreate и типа членов ViewerRecord. Один или несколько из них не имеют фиксированного размера, вероятно, строки.

Когда файл уже существует, все идет не так. Вы начнете записывать данные в начале файла, перезаписывая существующие данные. Но то, что вы пишете, только случайно перезаписывает существующую запись, строка должна быть точно такого же размера. Если вы не напишите достаточно записей, вы не будете перезаписывать все старые записи. И когда вы читаете файл, у вас возникают проблемы, вы читаете часть старой записи после того, как прочитали последнюю записанную запись. Вы получите мусор на некоторое время.

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

Если вам действительно нужно сохранить старые записи, вам следует добавить файл FileMode.Append. Если вы этого не сделаете, то вам следует переписать файл FileMode.Create.

...