GZipStream和解压缩

13 c# compression gzipstream

我有应该进行压缩的代码:

FileStream fs = new FileStream("g:\\gj.txt", FileMode.Open);
FileStream fd = new FileStream("g:\\gj.zip", FileMode.Create);
GZipStream csStream = new GZipStream(fd, CompressionMode.Compress);

byte[] compressedBuffer = new byte[500];
int offset = 0;
int nRead;

nRead = fs.Read(compressedBuffer, offset, compressedBuffer.Length);
while (nRead > 0)
{
    csStream.Write(compressedBuffer, offset, nRead);
    offset = offset + nRead;
    nRead = fs.Read(compressedBuffer, offset, compressedBuffer.Length);
}

fd.Close();
fs.Close();
Run Code Online (Sandbox Code Playgroud)

我认为确实如此,但我想解压缩上面压缩的内容.我这样想:

FileStream fd = new FileStream("g:\\gj.new", FileMode.Create);
FileStream fs = new FileStream("g:\\gj.zip", FileMode.Open);
GZipStream csStream = new GZipStream(fs, CompressionMode.Decompress);

byte[] decompressedBuffer = new byte[500];
int offset = 0;
int nRead;

nRead=csStream.Read(decompressedBuffer, offset, decompressedBuffer.Length);
while (nRead > 0)
{
    fd.Write(decompressedBuffer, offset, nRead);
    offset = offset + nRead;
    nRead = csStream.Read(decompressedBuffer, offset, decompressedBuffer.Length);
}

fd.Close();
fs.Close();
Run Code Online (Sandbox Code Playgroud)

在这里它没有...我有nRead = 0 befeore进入循环...我做错了什么?我使用的测试文件是最简单的TEXT文件(大小:104字节)...

Mar*_*ell 18

我的第一个想法是你没有关闭csStream.如果你使用using它会自动发生.由于gzip缓冲数据,你可能会遗漏一些.

其次; 不要增加offset; 这是缓冲区(不是流)的偏移量.离开0:

using (Stream fs = File.OpenRead("gj.txt"))
using (Stream fd = File.Create("gj.zip"))
using (Stream csStream = new GZipStream(fd, CompressionMode.Compress))
{
    byte[] buffer = new byte[1024];
    int nRead;
    while ((nRead = fs.Read(buffer, 0, buffer.Length))> 0)
    {
        csStream.Write(buffer, 0, nRead);
    }
}

using (Stream fd = File.Create("gj.new.txt"))
using (Stream fs = File.OpenRead("gj.zip"))
using (Stream csStream = new GZipStream(fs, CompressionMode.Decompress))
{
    byte[] buffer = new byte[1024];
    int nRead;
    while ((nRead = csStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        fd.Write(buffer, 0, nRead);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您也可以使用内置的.CopyTo()函数代替缓冲循环.在这种情况下,它将是:csStream.CopyTo(fd); (5认同)
  • 好点,只是增加了一点知识.我在GZipStream中找到的另一件烦人的事情.如果您要写入MemoryStream,则必须.Close()GZipStream.否则它将保持最后几个字节..Flush()似乎没有做到这一点.(这是在using语句中使用MemoryStream.) (2认同)

Ste*_*mes 12

我有两种方法就像詹姆斯·罗兰提到的那样。

private static byte[] Compress(HttpPostedFileBase file)
{
    using var to = new MemoryStream();
    using var gZipStream = new GZipStream(to, CompressionMode.Compress);
    file.InputStream.CopyTo(gZipStream);
    gZipStream.Flush();
    return to.ToArray();
}

private static byte[] Decompress(byte[] compressed)
{
    using var from = new MemoryStream(compressed);
    using var to = new MemoryStream();
    using var gZipStream = new GZipStream(from, CompressionMode.Decompress);
    gZipStream.CopyTo(to);
    return to.ToArray();
}
Run Code Online (Sandbox Code Playgroud)

但是,我正在使用上传

Request.Files[0] 
Run Code Online (Sandbox Code Playgroud)

然后压缩并保存在数据库中。然后我把img拉出来,解压并设置一个src

$"data:image/gif;base64,{ToBase64String(Decompress(img))}";
Run Code Online (Sandbox Code Playgroud)

  • @JCKödel虽然它显然更喜欢在可能的情况下利用“使用”,但说“从不”并不准确,而且在很多情况下这是不希望和/或不可能的。 (3认同)