【问题标题】:Asynchronous Reading/Writing to same stream?异步读/写到同一个流?
【发布时间】:2012-08-14 01:34:29
【问题描述】:

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

问题:

  1. 从 GET 返回的响应流不可搜索,因此无法传递给 PUT 请求并使其无缝地从一个流向另一个
  2. 使用 CopyTo() 将响应流复制到中间流 (MemoryStream),然后将其传递给 PUT 操作效果很好,但无法扩展(大文件会引发 OutOfMemory 异常)

所以基本上我需要一个可以同时读/写的中间流,基本上我会从响应流中读取一个块并将其写入我的中间流,同时 PUT 请求正在读取内容和它只是一种无缝的直通场景。

我在 stackoverflow 上找到了这篇文章,起初它看起来很有希望,但它仍然会引发大文件的 OutOfMemory 异常。

.NET Asynchronous stream read/write

有人做过类似的事情吗?你将如何应对?提前感谢

【问题讨论】:

  • 这接近 BufferedStream。除了 seek,如果输入流不支持则不支持。目前还不是很清楚为什么需要搜索以及需要可搜索的范围。

标签: c# io .net


【解决方案1】:

我找到了这个,但它在内部使用了一个队列,作者指出它比 MemoryStream 慢一个数量级。

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

我一直希望我能找到一个官方的 MS 库解决方案,但似乎这个轮子还没有被正确地发明出来。

【讨论】:

    【解决方案2】:

    不清楚您为什么要使用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);
        }
    }
    

    【讨论】:

    • 在PUT请求的入站响应流和出站流之间使用MemoryStream的主要原因是前者不支持'seek'操作,所以不能直接作为源传递到 PUT 请求。这有意义吗?
    • @snappymcsnap:那么你能不能写入 PUT 请求作为流?
    • PutObjectRequest 对象只有一个属性来指定要使用的 InputStream,它本身不支持直接写入操作
    • @snappymcsnap:好的,这更有意义。听起来您可能需要将其作为中间文件写入磁盘。
    • 我希望有一种更优雅的方式来做,我可以将字节汇集到一端,同时读出另一端。我很感谢你的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 2019-03-04
    • 2011-04-05
    • 2016-11-17
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    相关资源
    最近更新 更多