首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用GZipStream进行压缩

使用GZipStream进行压缩
EN

Stack Overflow用户
提问于 2013-01-13 03:27:08
回答 4查看 46.5K关注 0票数 13

我正在尝试理解为什么我的代码不能按预期执行。它创建一个GZipStream,然后将对象作为压缩文件保存在我的硬盘上,但保存的文件始终为0字节。

现在我知道如何save a file using GZipStream,但我的问题不是如何做到这一点。我的问题纯粹是为什么这段代码可以节省0个字节(或者为什么FileStream可以工作,而内存不行)。

代码语言:javascript
复制
private void BegingCompression()
{
    var bytes = File.ReadAllBytes(this.fileName);
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        ms.ReadByte();
        using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew))
        using (GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, false))
        {
            zipStream.Write(bytes, 0, bytes.Length);
        }
    }
}

关于源代码,this.fileName = c:\Audio.wavnewFileNamec:\Audio.wav.gz (但也尝试过c:\audio.gz)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-01-13 03:40:23

  • 您不需要MemoryStream,因为bytes已经有要压缩的数据。不应使用
  • ms.ReadByte()
  • 创建zipStream时,应使用输出文件流。

试试这个:

代码语言:javascript
复制
var bytes = File.ReadAllBytes(this.fileName);
using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew))
using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress, false))
{
     zipStream.Write(bytes, 0, bytes.Length);
}

编辑

原始代码会创建一个长度为零的文件,因为您不会写入文件流。

票数 17
EN

Stack Overflow用户

发布于 2013-01-13 04:40:17

System.IO.Compression命名空间中使用GzipStreamDeflateStream时,您在构造函数中提供的Stream将被写入以用于压缩,并从decompression.中的读取

由于您试图在此处压缩数据,因此使用MemoryStream是不正确的,因为您不是试图压缩到它,而是将其用作数据源。因此,您的MemoryStream应该是输入StreamFileStream应该是您的输出。

我强烈建议您使用MemoryStream作为数据源,而不是原始的byte[],因为Stream具有更多的通用性和应用程序(FileStreamNetworkStreamCryptoStream等)。

以下是使用async/await模式的一些示例:

代码语言:javascript
复制
public static async Task CompressToFileAsync(byte[] buffer, 
                                             string outputFile)
{
  using (var inputStream = new MemoryStream(buffer))
    await CompressToFileAsync(inputStream, outputFile);
}

public static async Task CompressToFileAsync(Stream inputStream, 
                                             string outputFile)
{
  using (var outputStream = File.Create(outputFile))
  using (var gzip = new GZipStream(outputStream, CompressionMode.Compress))
  {
    await inputStream.CopyToAsync(gzip);
    gzip.Close();
  }
}

public static async Task<MemoryStream> DecompressFromFileAsync(string inputFile)
{
  var outputStream = new MemoryStream();

  using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read))
  using (var gzip = new GZipStream(inputStream, CompressionMode.Decompress))
  {
    await gzip.CopyToAsync(outputStream);

    gzip.Close();
    inputStream.Close();

    // After writing to the MemoryStream, the position will be the size
    // of the decompressed file, we should reset it back to zero before returning.
    outputStream.Position = 0;
    return outputStream;
  }
}

注意:总是在关闭输入或输出Stream之前调用GzipStream.Close()。它在关闭/释放时执行一些最终的缓冲区刷新,如果输入或输出首先被关闭,它将在尝试这样做时抛出异常。(这也适用于DeflateStream)

票数 11
EN

Stack Overflow用户

发布于 2018-05-04 23:23:08

我使用这个类进行压缩/解压缩:

代码语言:javascript
复制
internal class GZipProcessor : IZipProcessor
{

    public byte[] Compress(byte[] data)
    {
        using (var compressedStream = new MemoryStream())
        {
            using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
            {
                zipStream.Write(data, 0, data.Length);
                zipStream.Close();
                return compressedStream.ToArray();
            }
        }
    }

    public byte[] Decompress(byte[] data)
    {
        using (var compressedStream = new MemoryStream(data))
        {
            using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
            {
                using (var resultStream = new MemoryStream())
                {
                    zipStream.CopyTo(resultStream);
                    return resultStream.ToArray();
                }
            }
        }
    }

}

以及如何使用它:

代码语言:javascript
复制
public void Compress(string inputPath, string outputPath)
{
    byte[] originalBytes = File.ReadAllBytes(inputPath);
    byte[] zippedBytes = base.ZipProcessor.Compress(originalBytes);
    File.WriteAllBytes(outputPath, zippedBytes);
}

public void Decompress(string inputPath, string outputPath)
{
    byte[] zippedBytes = File.ReadAllBytes(inputPath);
    byte[] originalBytes = base.ZipProcessor.Decompress(zippedBytes);
    File.WriteAllBytes(outputPath, originalBytes);
}

此外,我还有一个包含更复杂代码的github repository

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

https://stackoverflow.com/questions/14297077

复制
相关文章

相似问题

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