在.net 2.0中的两个流之间复制

时间:2011-09-14 22:05:52

标签: c# winforms stream copy

我一直在使用以下代码来压缩.Net 4.0中的数据:

public static byte[] CompressData(byte[] data_toCompress)
{

    using (MemoryStream outFile = new MemoryStream())
    {
        using (MemoryStream inFile = new MemoryStream(data_toCompress))
        using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress))
        {
            inFile.CopyTo(Compress);

        }
        return outFile.ToArray();
    }

}

但是,在.Net 2.0中,Stream.CopyTo方法不可用。所以,我试着替换:

public static byte[] CompressData(byte[] data_toCompress)
{

    using (MemoryStream outFile = new MemoryStream())
    {
        using (MemoryStream inFile = new MemoryStream(data_toCompress))
        using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress))
        {
            //inFile.CopyTo(Compress);
            Compress.Write(inFile.GetBuffer(), (int)inFile.Position, (int)(inFile.Length - inFile.Position));
        }
        return outFile.ToArray();
    }

}

但是,当使用上述尝试时压缩失败 - 我收到错误消息:

  

无法访问MemoryStream的内部缓冲区。

有人可以就此问题提供任何帮助吗?我真的不确定这里还能做什么。

谢谢你, 埃文

7 个答案:

答案 0 :(得分:7)

这是直接来自.Net 4.0 Stream.CopyTo方法的代码(bufferSize为4096):

byte[] buffer = new byte[bufferSize];
int count;
while ((count = this.Read(buffer, 0, buffer.Length)) != 0)
    destination.Write(buffer, 0, count);

答案 1 :(得分:3)

由于您已经可以访问该阵列,为什么不这样做:

using (MemoryStream outFile = new MemoryStream())
{
    using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress))
    {
        Compress.Write(data_toCompress, 0, data_toCompress.Length);
    }
    return outFile.ToArray();
}

您使用的示例代码中最有可能inFile.GetBuffer()将抛出异常,因为您不使用right constructor - 并非所有MemoryStream实例都允许您访问内部缓冲区 - 您必须在文档中查找:

  

基于的初始化MemoryStream类的新实例   指定的字节数组区域,CanWrite属性设置为   指定,以及调用GetBuffer设置为指定的能力

这应该有效 - 但无论如何在建议的解决方案中都不需要:

using (MemoryStream inFile = new MemoryStream(data_toCompress, 
                                              0, 
                                              data_toCompress.Length, 
                                              false, 
                                              true))

答案 2 :(得分:0)

为什么要使用数组构造内存流,然后尝试将数组拉出内存流?

您可以Compress.Write(data_toCompress, 0, data_toCompress.Length);

如果需要替换CopyTo的功能,可以创建一个长度的缓冲区数组,从源流中读取数据并将该数据写入目标流。

答案 3 :(得分:0)

你可以尝试

infile.WriteTo(Compress);

答案 4 :(得分:0)

尝试替换该行:

Compress.Write(inFile.GetBuffer(), (int)inFile.Position, (int)(inFile.Length - inFile.Position));

使用:

Compress.Write(data_toCompress, 0, data_toCompress.Length);

你可以完全摆脱这条线:

using (MemoryStream inFile = new MemoryStream(data_toCompress))

修改:在此处查找示例:Why does gzip/deflate compressing a small file result in many trailing zeroes?

答案 5 :(得分:0)

您应该在这两个流之间手动读写:

    private static void CopyStream(Stream from, Stream to)
    {
        int bufSize = 1024, count;
        byte[] buffer = new byte[bufSize];
        count = from.Read(buffer, 0, bufSize);
        while (count > 0)
        {
            to.Write(buffer, 0, count);
            count = from.Read(buffer, 0, bufSize);
        }
    }

答案 6 :(得分:0)

开源NuGet包Stream.CopyTo为所有版本的.NET Framework实现Stream.CopyTo

Available on GitHubvia NuGetInstall-Package Stream.CopyTo