如何从头开始复制流,而不考虑其当前位置



我得到了一个文件流,其中包含从磁盘读取的内容。

    Stream input = new FileStream("filename");

此流将被传递到第三方库,该库在读取流后,将流的位置指针保留在文件末尾(作为使用)。

我的要求不是每次都从桌面加载文件,而是要维护每次都会使用的MemoryStream

    public static void CopyStream(Stream input, Stream output)
    {
        byte[] buffer = new byte[32768];
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            output.Write(buffer, 0, read);
        }
    }

我已经尝试了上面的代码。将输入流复制到输出流是第一次工作,但对CopyStream的后续调用将不起作用,因为源的Position将在第一次调用后位于流的末尾。

是否有其他替代方法可以将源流的内容复制到另一个流,而不管源流的当前Position如何?

并且此代码需要在多线程环境中以线程安全的方式运行。

您可以使用 .NET 4.0 Stream.CopyTo 将 Steam 复制到 MemoryStream。内存流有一个 Position 属性,可用于将其位置移动到开头。

var ms = new MemoryStream();
using (Stream file = File.OpenRead(@"filename"))
{
   file.CopyTo(ms);
}
ms.Position = 0;

要使线程安全解决方案,您可以将内容复制到字节数组,并为需要访问的每个线程创建一个新的 MemoryStream 包装字节数组:

byte[] fileBytes = ms.ToArray();
var ms2 = new MemoryStream(fileBytes);

您应该检查输入流的 CanSeek 属性。如果返回 false,则无论如何您只能读取一次。如果CanSeek返回 true,则可以将位置设置为零并复制掉。

if (input.CanSeek)
{
    input.Position = 0;
}

您可能还希望存储旧位置并在复制后恢复它。

ETA:传递相同的Stream实例并不是最安全的做法。 例如,当您取回Stream时,您无法确定它没有被处理掉。我建议一开始就将FileStream复制到MemoryStream,但只通过调用ToArray()来存储后者的字节内容。当您需要在某处传递Stream时,只需每次使用 new MemoryStream(byte[]) 创建一个新即可。

相关内容

  • 没有找到相关文章

最新更新