用GZipStream压缩

Dav*_*ave 10 .net c#

我试图理解为什么我的代码没有按照需要执行.它创建一个GZipStream,然后将该对象保存为我的硬盘驱动器上的压缩文件,但保存的文件始终为0字节.

现在我知道如何使用GZipStream保存文件,但是,我的问题不是如何做到这一点.我的问题纯粹是为什么这段代码可以节省0个字节(或者为什么FileStream工作而内存不存在).

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在问候的源代码,this.fileName = c:\Audio.wav以及newFileNameIS c:\Audio.wav.gz(但也试过c:\audio.gz)

Ric*_*der 15

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

试试这个:

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);
}
Run Code Online (Sandbox Code Playgroud)

编辑

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


Eri*_*rik 10

当您使用GzipStreamDeflateStreamSystem.IO.Compression命名空间中,Stream您在供应构造函数将被写入压缩读取减压.

由于您尝试在此处压缩数据,因此使用MemoryStream不正确,因为您不是要尝试压缩数据,而是将其用作数据源.所以你MemoryStream应该是输入Stream,这FileStream是你的输出.

我强烈建议你使用MemoryStream作为在原始数据源byte[],因为Stream有很多更多的功能和应用程序(FileStream,NetworkStream,CryptoStream等)

以下是使用async/ awaitpattern的一些示例:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:GzipStream.Close()在关闭输入输出 之前始终呼叫Stream.它在关闭/处理时执行一些最终缓冲区刷新,如果输入输出先关闭,它会在尝试执行此操作时抛出异常.(这也适用于DeflateStream)


isx*_*ker 5

我使用这个类来压缩/解压缩:

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();
                }
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

以及我如何使用它:

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);
}
Run Code Online (Sandbox Code Playgroud)

我还有一个包含更复杂代码的github 存储库