本文介绍了Stream.Copy 是管道传输吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我正在编写一个 tcp 代理代码.我正在从传入流中读取并写入输出流.我知道 Stream.Copy 使用缓冲区,但我的问题是:Stream.Copy 方法是在从输入流中获取下一个块时写入输出流,还是像从输入读取块、将块写入到输出、从输入读取块等"这样的循环?

Suppose I am writing a tcp proxy code.I am reading from the incoming stream and writing to the output stream.I know that Stream.Copy uses a buffer, but my question is:Does the Stream.Copy method writes to the output stream while fetching the next chunk from the input stream or it a loop like "read chunk from input, write chunk to ouput, read chunk from input, etc" ?

推荐答案

以下是 .NET 4.5 中 CopyTo 的实现:

Here's the implementation of CopyTo in .NET 4.5:

private void InternalCopyTo(Stream destination, int bufferSize)
{
    int num;
    byte[] buffer = new byte[bufferSize];
    while ((num = this.Read(buffer, 0, buffer.Length)) != 0)
    {
        destination.Write(buffer, 0, num);
    }
}

如您所见,它从源读取,然后写入目标.这可能可以改进;)

So as you can see, it reads from the source, then writes to the destination. This could probably be improved ;)

这是管道版本的可能实现:

here's a possible implementation of a piped version:

public static void CopyToPiped(this Stream source, Stream destination, int bufferSize = 0x14000)
{
    byte[] readBuffer = new byte[bufferSize];
    byte[] writeBuffer = new byte[bufferSize];

    int bytesRead = source.Read(readBuffer, 0, bufferSize);
    while (bytesRead > 0)
    {
        Swap(ref readBuffer, ref writeBuffer);
        var iar = destination.BeginWrite(writeBuffer, 0, bytesRead, null, null);
        bytesRead = source.Read(readBuffer, 0, bufferSize);
        destination.EndWrite(iar);
    }
}

static void Swap<T>(ref T x, ref T y)
{
    T tmp = x;
    x = y;
    y = tmp;
}

基本上,它同步读取一个块,开始将其异步复制到目的地,然后读取下一个块并等待写入完成.

Basically, it reads a chunk synchronously, starts to copy it to the destination asynchronously, then read the next chunk and waits for the write to complete.

我进行了一些性能测试:

I ran a few performance tests:

  • 使用MemoryStreams,我没想到会有显着的改进,因为它不使用IO完成端口(AFAIK);事实上,性能几乎相同
  • 使用不同驱动器上的文件,我预计管道版本的性能会更好,但事实并非如此……它实际上稍微慢了一点(5% 到 10%)
  • using MemoryStreams, I didn't expect a significant improvement, since it doesn't use IO completion ports (AFAIK); and indeed, the performance is almost identical
  • using files on different drives, I expected the piped version to perform better, but it doesn't... it's actually slightly slower (by 5 to 10%)

所以它显然没有带来任何好处,这可能是它没有以这种方式实现的原因......

So it apparently doesn't bring any benefit, which is probably the reason why it isn't implemented this way...

这篇关于Stream.Copy 是管道传输吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 05:11