C# 如何使用 zlib.NET 扩充文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/185690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to inflate a file with zlib.NET?
提问by Ben Collins
I'm using the zlib.NETlibrary to try and inflate files that are compressed by zlib (on a Linux box, perhaps). Here's what I'm doing:
我正在使用zlib.NET库来尝试扩充由 zlib 压缩的文件(可能在 Linux 机器上)。这是我在做什么:
zlib.ZInputStream zinput =
new zlib.ZInputStream(File.Open(path, FileMode.Open, FileAccess.Read));
while (stopByte != (data = zinput.ReadByte()))
{
// check data here
}
zinput.Close();
The data bytes match the compressed data bytes, so I must be doing something wrong.
数据字节与压缩数据字节匹配,所以我一定是做错了什么。
采纳答案by Ben Collins
It appears I made the mistake of assuming all virtual methods were overridden, which wasn't the case. I was using zlib.ZInputStream.ReadByte(), which is just the inherited Stream.ReadByte(), which doesn't do any inflate.
看来我错误地假设所有虚拟方法都被覆盖了,但事实并非如此。我使用的是 zlib.ZInputStream.ReadByte(),它只是继承的 Stream.ReadByte(),它不做任何膨胀。
I used zlib.ZInputStream.Read() instead, and it worked like it should.
我用 zlib.ZInputStream.Read() 代替,它像它应该的那样工作。
回答by Jon Skeet
Other than failing to use a "using" statement to close the stream even in the face of an exception, that looks okay to me. Is the data definitely compressed? Are you able to decompress it with zlib on the linux box?
除了即使遇到异常也未能使用“使用”语句关闭流之外,这对我来说看起来还不错。数据肯定被压缩了吗?你能在linux盒子上用zlib解压吗?
Having looked at the source code, it's pretty ghastly - a call to int Read(buffer, offset, length)
will end up calling its internal int Read()
method length
times for example. Given that sort of shaky start, I'm not sure I'd trust the code particularly heavily, but I'd have expected it to work at least slightly! Have you tried using SharpZipLib?
查看源代码后,它非常可怕 - 例如,调用int Read(buffer, offset, length)
将最终调用其内部int Read()
方法length
时间。鉴于这种不稳定的开始,我不确定我会特别信任代码,但我希望它至少能稍微工作!您是否尝试过使用SharpZipLib?
回答by Brendan Kowitz
Look at the sample code more closely, it is copying data from a regular Filestream to the ZOutputStream. The decompression must be happening through that layer.
更仔细地查看示例代码,它将数据从常规 Filestream 复制到 ZOutputStream。必须通过该层进行减压。
private void decompressFile(string inFile, string outFile)
{
System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
try
{
CopyStream(inFileStream, outZStream);
}
finally
{
outZStream.Close();
outFileStream.Close();
inFileStream.Close();
}
}
回答by Ben Collins
The below code could help you guys. Instantiate the object and make use of the functions.
下面的代码可以帮助你们。实例化对象并使用函数。
public class FileCompressionUtility
{
public FileCompressionUtility()
{
}
public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}
public void compressFile(string inFile, string outFile)
{
System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION);
System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
try
{
CopyStream(inFileStream, outZStream);
}
finally
{
outZStream.Close();
outFileStream.Close();
inFileStream.Close();
}
}
public void uncompressFile(string inFile, string outFile)
{
int data = 0;
int stopByte = -1;
System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
zlib.ZInputStream inZStream = new zlib.ZInputStream(System.IO.File.Open(inFile, System.IO.FileMode.Open, System.IO.FileAccess.Read));
while (stopByte != (data = inZStream.Read()))
{
byte _dataByte = (byte)data;
outFileStream.WriteByte(_dataByte);
}
inZStream.Close();
outFileStream.Close();
}
}
回答by Scotty.NET
I recently had the misfortune of serving out docs previously zlib'd using php to a variety of browsers and platforms including IE7. Once I figured out that the docs were zlib'd and not gzip'd (as was thought at the time) I used SharpZipLibin the following way in .NET Framework v4 (taking advantage of Stream.CopyTo):
我最近不幸将以前 zlib 使用 php 的文档提供给包括 IE7 在内的各种浏览器和平台。一旦我发现文档是 zlib'd 而不是 gzip'd(当时认为),我在 .NET Framework v4 中以下列方式使用SharpZipLib(利用Stream.CopyTo):
public static byte[] DecompressZlib(Stream source)
{
byte[] result = null;
using (MemoryStream outStream = new MemoryStream())
{
using (InflaterInputStream inf = new InflaterInputStream(source))
{
inf.CopyTo(outStream);
}
result = outStream.ToArray();
}
return result;
}
Thought I would put it here in case anyone needs help with the classes to use from SharpZipLib.
我想我会把它放在这里,以防万一有人需要从 SharpZipLib 使用的类的帮助。
回答by CodesInChaos
Skipping the zlib header (first two bytes, 78 9C
) and then using the DeflateStream
built into .net worked for me.
跳过 zlib 标头(前两个字节,78 9C
),然后使用DeflateStream
.net 内置的对我有用。
using(var input = File.OpenRead(...))
using(var output = File.Create(...))
{
// if there are additional headers before the zlib header, you can skip them:
// input.Seek(xxx, SeekOrigin.Current);
if (input.ReadByte() != 0x78 || input.ReadByte() != 0x9C)//zlib header
throw new Exception("Incorrect zlib header");
using (var deflateStream = new DeflateStream(decryptedData, CompressionMode.Decompress, true))
{
deflateStream.CopyTo(output);
}
}