将一个流的内容复制到另一个流的最佳方法是什么?有标准的实用方法吗?


当前回答

我使用以下扩展方法。当一个流是MemoryStream时,他们优化了重载。

    public static void CopyTo(this Stream src, Stream dest)
    {
        int size = (src.CanSeek) ? Math.Min((int)(src.Length - src.Position), 0x2000) : 0x2000;
        byte[] buffer = new byte[size];
        int n;
        do
        {
            n = src.Read(buffer, 0, buffer.Length);
            dest.Write(buffer, 0, n);
        } while (n != 0);           
    }

    public static void CopyTo(this MemoryStream src, Stream dest)
    {
        dest.Write(src.GetBuffer(), (int)src.Position, (int)(src.Length - src.Position));
    }

    public static void CopyTo(this Stream src, MemoryStream dest)
    {
        if (src.CanSeek)
        {
            int pos = (int)dest.Position;
            int length = (int)(src.Length - src.Position) + pos;
            dest.SetLength(length); 

            while(pos < length)                
                pos += src.Read(dest.GetBuffer(), pos, length - pos);
        }
        else
            src.CopyTo((Stream)dest);
    }

其他回答

实际上,有一种更简单的方法来做流复制。但是请注意,这意味着您可以将整个文件存储在内存中。如果您正在处理数百兆字节或更大的文件,请不要轻率地尝试使用此功能。

public static void CopySmallTextStream(Stream input, Stream output)
{
  using (StreamReader reader = new StreamReader(input))
  using (StreamWriter writer = new StreamWriter(output))
  {
    writer.Write(reader.ReadToEnd());
  }
}

注意:关于二进制数据和字符编码也可能存在一些问题。

MemoryStream有.WriteTo(outstream);

. net 4.0在普通流对象上有. copyto。

net 4.0:

instream.CopyTo(outstream);

下面的代码可以解决这个问题,使用CopyTo将流复制到MemoryStream

Stream stream = new MemoryStream();

//任何需要输入流的函数。在我的情况下,保存PDF文件为流 document.Save(流);

MemoryStream newMs = (MemoryStream)stream;

byte[] getByte = newMs.ToArray();

//注意-请在finally块中处理流,而不是在using块中处理,因为它会抛出一个错误'访问被拒绝,因为流被关闭'

. net Framework 4引入了新的系统流类的CopyTo方法。IO命名空间。使用此方法,我们可以将一个流复制到不同流类的另一个流。

这里有一个例子。

    FileStream objFileStream = File.Open(Server.MapPath("TextFile.txt"), FileMode.Open);
    Response.Write(string.Format("FileStream Content length: {0}", objFileStream.Length.ToString()));

    MemoryStream objMemoryStream = new MemoryStream();

    // Copy File Stream to Memory Stream using CopyTo method
    objFileStream.CopyTo(objMemoryStream);
    Response.Write("<br/><br/>");
    Response.Write(string.Format("MemoryStream Content length: {0}", objMemoryStream.Length.ToString()));
    Response.Write("<br/><br/>");

可能有一种方法可以更有效地做到这一点,这取决于您处理的是哪种流。如果可以将一个或两个流转换为MemoryStream,则可以使用GetBuffer方法直接处理表示数据的字节数组。这让你可以使用像Array这样的方法。CopyTo,它抽象了fryguybob提出的所有问题。你可以相信. net知道复制数据的最佳方式。