2010-07-22 69 views
0

我有一种方法,它使用二进制打字机写一个记录组成的几个提示和一个字节数组到文件。作为我的程序的一部分,此方法每秒执行十几次。代码如下:二进制打字机不打开文件在流结束

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

上面的代码工作正常,但如果我删除与寻求通话线路,产生的二进制文件已损坏。例如,某些记录完全丢失,或者其中的一部分不存在,尽管绝大多数记录都写得很好。所以我想象错误的原因是当我反复打开和关闭文件时,文件中的当前位置并不总是在末尾,事情会被覆盖。

所以我的问题是:为什么不是C#确保当前位置在最后打开文件时?

PS:我从如果要追加到文件造成这个错误

回答

1

问题是FileMode.OpenOrCreate和ViewerRecord成员类型的组合。其中一个或多个不是固定大小的类型,可能是一个字符串。

当文件已经存在时事情就出错了。您将开始在文件开始处写入数据,覆盖现有数据。但是你写的只是偶然地覆盖现有的记录,字符串必须是完全相同的大小。如果你没有写足够的记录,那么你将不会覆盖所有的旧记录。当你阅读文件时会遇到麻烦,你会在阅读最后一个书面记录后阅读旧记录的一部分。你会得到一段时间的垃圾。

将记录制作成固定大小并不能真正解决问题,您会看到一个很好的记录,但它会是一个旧记录。你会得到哪一组特定的旧记录取决于你写了多少新数据。这应该与读取乱码数据一样糟糕。

如果您确实需要保留旧记录,那么您应该追加到文件FileMode.Append。如果你不这样做,你应该重写文件FileMode.Create。

+0

解释一下,欢呼:) – CalumMcCall 2010-07-22 16:38:34

4

排除线程问题,您必须在打开调用中使用FileMode.Append,否则文件将其位置设置为打开文件的开始,而不是结束。

+0

很确实,我应该在我的帖子中指出这一点。然而,为什么我仍然会得到大量的记录,包括第一个记录,没有任何问题,然后在文件的中间位置,我记录了一半的记录,然后它们也很好。追加还是缺乏,不会造成这种情况呢?当然,我只应该得到实际存在于文件中的最后一个记录列表? – CalumMcCall 2010-07-22 15:25:39

+0

那么你发布的代码实际上并不是有问题的代码? – 2010-07-22 15:41:46

相关问题