.Net BinaryWriter 在检查流位置时自动刷新流

.Net BinaryWriter automatically flushes stream when checking stream Position

有没有其他人看到这个或知道如何关闭它?

我有代码定期检查 BinaryWriter 中流的位置。每次调用 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

框架容易刷屏,是的。这很糟糕,因为它会强制访问磁盘。 (主观说明:这是一个设计缺陷。)

给自己写一个 Stream 来包装另一个流。在您的包装器 class 中,您覆盖了必要的方法以在实例字段中自己维护 Position。这样,根本不需要访问包装流的 Position 成员。

看起来 BinaryWriter class 强制过度刷新并且无法覆盖它。我将只保留对原始流的引用并直接检查它的位置。

我在这里找到了(所谓的)源代码:

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