首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DeflateStream:读取时压缩文件

DeflateStream:读取时压缩文件
EN

Stack Overflow用户
提问于 2012-05-09 16:07:20
回答 5查看 4.9K关注 0票数 3

我试图通过WCF (一些GBs)发送大量数据。我想在使用流读取文件时压缩文件,但是看起来DeflateStream有两种模式:

  • 压缩(写入流)
  • 解压(读取流)

在我的情况下,这些模式都不起作用。我想从磁盘读取一个未压缩的文件,并通过WCF返回一个压缩流。

是否有办法这样做,或者我必须使用一个时态文件(或MemoryStream)?

是一个缺失的功能,还是因为某种原因而不可能?

EN

回答 5

Stack Overflow用户

发布于 2012-05-09 16:33:41

尝试使用这些方法来压缩和解压缩字节数组。

代码语言:javascript
复制
    private static byte[] Compress(byte[] data)
    {
        byte[] retVal;
        using (MemoryStream compressedMemoryStream = new MemoryStream())
        {
            DeflateStream compressStream = new DeflateStream(compressedMemoryStream, CompressionMode.Compress, true);
            compressStream.Write(data, 0, data.Length);
            compressStream.Close();
            retVal = new byte[compressedMemoryStream.Length];
            compressedMemoryStream.Position = 0L;
            compressedMemoryStream.Read(retVal, 0, retVal.Length);
            compressedMemoryStream.Close();
            compressStream.Close();
        }
        return retVal;
    }



    private static byte[] Decompress(byte[] data)
    {
        byte[] retVal;
        using (MemoryStream compressedMemoryStream = new MemoryStream())
        {
            compressedMemoryStream.Write(data, 0, data.Length);
            compressedMemoryStream.Position = 0L;
            MemoryStream decompressedMemoryStream = new MemoryStream();
            DeflateStream decompressStream = new DeflateStream(compressedMemoryStream, CompressionMode.Decompress);
            decompressStream.CopyTo(decompressedMemoryStream);
            retVal = new byte[decompressedMemoryStream.Length];
            decompressedMemoryStream.Position = 0L;
            decompressedMemoryStream.Read(retVal, 0, retVal.Length);
            compressedMemoryStream.Close();
            decompressedMemoryStream.Close();
            decompressStream.Close();
        }
        return retVal;
}
票数 3
EN

Stack Overflow用户

发布于 2012-05-09 16:18:21

你应该有这样的东西:

代码语言:javascript
复制
public void CompressData(Stream uncompressedSourceStream, Stream compressedDestinationStream)
{
    using (DeflateStream compressionStream = new DeflateStream(compressedDestinationStream, CompressionMode.Compress))
    {
        uncompressedSourceStream.CopyTo(compressionStream);
    }
}

public void DecompressData(Stream compressedSourceStream, Stream uncompressedDestinationStream)
{
    using (DeflateStream decompressionStream = new DeflateStream(uncompressedDestinationStream, CompressionMode.Decompress))
    {
        compressedSourceStream.CopyTo(decompressionStream);
    }
}

using (FileStream sourceStream = File.OpenRead(@"C:\MyDir\MyFile.txt))
using (FileStream destinationStream = File.OpenWrite(@"C:\MyDir\MyCompressedFile.txt.cp"))
{
    CompressData(sourceStream, destinationStream)
}

另外,请注意,您可能必须更改应用程序的.config文件中的WCF设置,以允许进行非常大的传输。

票数 2
EN

Stack Overflow用户

发布于 2014-04-10 23:08:04

您可以将DeflateStream封装在自己的流中。每次您想从压缩流中读取数据时,都必须将字节输入到平减存储器中,直到它写入缓冲区为止。然后,可以从该缓冲区返回字节。

代码语言:javascript
复制
public class CompressingStream : Stream
{
    private readonly DeflateStream _deflateStream;
    private readonly MemoryStream _buffer;
    private Stream _inputStream;
    private readonly byte[] _fileBuffer = new byte[64 * 1024];

    public CompressingStream(Stream inputStream)
    {
        _inputStream = inputStream;
        _buffer = new MemoryStream();
        _deflateStream = new DeflateStream(_buffer, CompressionMode.Compress, true);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        while (true)
        {
            var read = _buffer.Read(buffer, offset, count);

            if (read > 0) return read;

            if (_inputStream == null) return 0;

            _buffer.Position = 0;
            read = _inputStream.Read(_fileBuffer, 0, _fileBuffer.Length);
            if (read == 0)
            {
                _inputStream.Close();
                _inputStream = null;
                _deflateStream.Close();
            }
            else
            {
                _deflateStream.Write(_fileBuffer, 0, read);
            }
            _buffer.SetLength(_buffer.Position);
            _buffer.Position = 0;
        }
    }

    public override bool CanRead
    {
        get { return true; }
    }
#region Remaining overrides...
}

每当wcf从流中读取时,压缩流将写入压缩DeflateStream,直到它从输出缓冲区(_buffer)读取为止。很丑,但很管用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10519868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档