其他人见过这个或知道如何关闭它吗?
我有代码可以定期检查流在二进制编写器中的位置。 每次调用 BinaryWriter.BaseStream.Position 方法都会导致调用该流的 Flush 方法。
我尝试使用 BinaryWriter 和 StreamWriter,只有 BinaryWriter 演示了这种行为。
下面是一些示例代码:
namespace FlushaholicStreams
{
class Program
{
static void Main(string[] args)
{
using (var stream = new PrivateStream())
using (var writer = new BinaryWriter(stream))
{
var data = "hi there, this is a really long string. Very very very long";
for (int i = 0; i < 19; i++)
{
data += data;
}
for (int j = 0; j < 8; j++)
{
var bytes = Encoding.ASCII.GetBytes(data);
writer.Write(bytes);
var position = writer.BaseStream.Position;
Console.WriteLine("The position was {0}", position);
}
}
Console.WriteLine("All done");
}
}
class PrivateStream : MemoryStream
{
public int FlushCount = 0;
public int CloseCount = 0;
public override void Close()
{
this.CloseCount++;
Console.WriteLine("Closing the stream");
base.Close();
}
public override void Flush()
{
this.FlushCount++;
Console.WriteLine("Flushing the stream");
base.Flush();
}
}
}
该代码生成输出:
Flushing the stream
The position was 30932992
Flushing the stream
The position was 61865984
Flushing the stream
The position was 92798976
Flushing the stream
The position was 123731968
Flushing the stream
The position was 154664960
Flushing the stream
The position was 185597952
Flushing the stream
The position was 216530944
Flushing the stream
The position was 247463936
Flushed the stream 8 times
Closing the stream
Closing the stream
All done
我正在使用 .Net 4.5
看起来 BinaryWriter 类强制过度刷新并且没有办法覆盖它。 我只会保留对原始流的引用并直接检查其位置。
我在这里找到了(据称的)源代码:
http://reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/IO/BinaryWriter@cs/1305376/BinaryWriter@cs
/*
* Returns the stream associate with the writer. It flushes all pending
* writes before returning. All subclasses should override Flush to
* ensure that all buffered data is sent to the stream.
*/
public virtual Stream BaseStream {
get {
Flush();
return OutStream;
}
}
// Clears all buffers for this writer and causes any buffered data to be
// written to the underlying device.
public virtual void Flush()
{
OutStream.Flush();
}
框架容易刷新,是的。这很糟糕,因为它强制访问磁盘。(主观说明:这是一个设计缺陷。
给自己写一个包装另一个流的Stream
。在包装类中,您可以重写在实例字段中自行维护Position
的必要方法。这样,根本不需要访问包装流的Position
成员。