3

假设我有一个流链,它执行 Compression -> Encryption -> File I/O。

在 C# 中,使用同步 I/O,它看起来像这样:

  int n=0;
  byte[] buffer= new byte[2048];
  string inputFileName = "input.txt";
  string outputFileName = inputFileName + ".compressed.encrypted";
  using (FileStream inputFileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read))
  {
      using (FileStream outputFileStream = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite))
      {
          using (Stream encryptor = new EncryptingStream(fs))
          {
              using (Stream compressor = new CompressorStream(encryptor))
              {
                  while ((n = inputFileStream.Read(buffer, 0, buffer.Length)) > 0)
                  {
                      compressor.Write(buffer, 0, n);
                  }
              }
          }
      }
  }

为了利用 FileStream 提供的异步 I/O,我想我不能简单地在压缩流上使用 BeginWrite() 方法。

在此示例中,为了利用 FileStream 上的异步 I/O,我认为 EncryptingStream 需要通过在包装的 Stream 上调用 BeginWrite/EndWrite 来实现 Write。如果包装的 Stream 是 FileStream,那么我会得到异步 I/O。那是对的吗?

4

1 回答 1

2

调用BeginWrite外部流(此处为compressor)将成功地将工作移至线程池,从而使其相对于调用方法异步执行。这可能足以满足您的应用程序,但这不是最大可能的效率。正如您所指出的,BeginWrite不会在FileStream实际执行磁盘 I/O 的内部使用。在BeginWrite那里使用时,FileStream的实现BeginWrite利用了提供更高可扩展性的“Windows 完成端口 API”。

另一种看待这一点的方式是从操作系统的角度来看,它不会是异步 I/O。但是,它将在线程池线程上同步运行,从而有效地使其与所有其他代码异步。要真正利用操作系统异步 I/O,您需要调用BeginWrite一个可以使用完成端口 API 的类。

我不确定您使用的是哪种压缩方式,因此请谨慎使用。例如,Stream您正在使用的可能甚至没有实现BeginWrite,或者它可能同步实现它。

于 2009-11-04T23:54:16.677 回答