需要在 FileStream 上的 Seek() 之前先 Flush() 吗?

问题描述 投票:0回答:1

我正在编写一个数据存储库,它将记录写入二进制文件中的特定位置。对于每个写入的记录,确定其在文件中的字节位置,将文件流查找到该位置,然后写入记录字节。

现在我观察到奇怪的行为,其中写入其他数据而不是传递给写入调用。有些记录只是重复的(覆盖相邻记录),其他记录在再次读取时纯粹是垃圾。该错误很少发生,但仍然时不时地损坏一些数据,这是不可接受的。也许是我的寻求和冲刷在这里不正确。由于缓冲区/刷新问题本质上是不可重现的,因此我无法编写测试用例来识别问题(还)。

代码如下:

// Init
var file = File.Open(fileName, FileMode.CreateNew);
var writer = new BinaryWriter(file, Encoding.UTF8, leaveOpen: true);

// For each record to write, in random order
long index = GetIndex(record.Time);
long newPosition = headerLength + index * recordLength;
file.Seek(newPosition, SeekOrigin.Begin);
writer.Write((byte)record.Flags);
writer.Write((double)record.Value);

// Closing
writer.Close();
file.Close();

所以我对每条记录进行查找,但不进行刷新。我想将磁盘写入操作保持在最低限度。调用者可以选择定期刷新文件。

如果我之前写入的数据仍然缓冲在某处,那么查找是否会破坏它?查找调用在内部使用了某种策略,我无法遵循该路径。不知道它内部在做什么。

我需要在任何 Seek() 之前显式调用 Flush() 吗?或者 FileStream 是否知道哪些数据需要发送到哪里?

.net filestream flush seek
1个回答
0
投票

基本上停止使用

BinaryWriter
。它有缓冲区,并且它不希望流在其下方移动。老实说,与直接使用
Stream
相比,它基本上没有添加任何内容 - 特别是如果您探索
BinaryPrimitives
API 之类的东西,例如
double
;您可以使用本地 stackalloc 跨度来完成此操作。

© www.soinside.com 2019 - 2024. All rights reserved.