异步读/写同一个流?

时间:2012-08-17 15:19:06

标签: c# io .net

有时我们需要在AWS S3中将大型文件从一个存储桶复制到另一个存储桶。我们尽可能使用CopyRequest在AWS上处理此操作(因为不需要回程到客户端)。但有时我们无法选择执行此操作,因为我们需要在2个完全独立的帐户之间进行复制,这需要GET,然后是PUT

问题:

  1. 从GET返回的响应流不可搜索,因此无法将其传递给PUT请求并使其无缝地从一个请求流到另一个
  2. 使用CopyTo()将响应流复制到中间流(MemoryStream),然后将其传递给PUT操作,但不能扩展(大文件会抛出OutOfMemory异常)
  3. 所以基本上我需要一个可以同时读/写的中间流,基本上我会从响应流中读取一个块并将其写入我的中间流,同时PUT请求正在读出内容和它只是一种无缝的传递方式。

    我在stackoverflow上发现了这篇文章,它起初似乎很有希望,但它仍然会抛出大文件的OutOfMemory异常。

    .NET Asynchronous stream read/write

    任何人都不得不做类似的事情吗?你会如何解决它?谢谢你的提议

2 个答案:

答案 0 :(得分:3)

目前尚不清楚为什么要使用MemoryStream。 .NET 4中的Stream.CopyTo方法不需要使用中间流 - 它只会读入固定大小的本地缓冲区,然后将该缓冲区写入输出流,然后读取更多数据(覆盖缓冲区)等。

如果您不使用.NET 4,则可以轻松实现类似的功能,例如

public static void CopyTo(this Stream input, Stream output)
{
    byte[] buffer = new byte[64 * 1024]; // 64K buffer
    int bytesRead;
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, bytesRead);
    }
}

答案 1 :(得分:3)

我发现了这一点,但它在内部使用了一个Queue,作者注意到它比MemoryStream慢了一个数量级。

http://www.codeproject.com/Articles/16011/PipeStream-a-Memory-Efficient-and-Thread-Safe-Stre

我一直希望我能找到一个官方的MS库解决方案,但似乎这个轮子尚未被正确发明。