zlib.NETでファイルを膨張させる方法は?
-
06-07-2019 - |
質問
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();
データバイトは圧縮されたデータバイトと一致するため、何か間違っている必要があります。
解決 2
すべての仮想メソッドがオーバーライドされたと仮定するのは間違いでしたが、そうではありませんでした。 zlib.ZInputStream.ReadByte()を使用していました。これは、継承されたStream.ReadByte()であり、膨張を行いません。
代わりにzlib.ZInputStream.Read()を使用しましたが、正常に機能しました。
他のヒント
"使用"の使用の失敗以外例外が発生した場合でもストリームを閉じるためのステートメント。データは完全に圧縮されていますか? Linuxボックスでzlibを使用して解凍できますか?
ソースコードを見たのは非常に恐ろしいことです- int Read(buffer、offset、length)
を呼び出すと、内部の int Read()
が呼び出されますたとえば、 length
回。そのような不安定なスタートを考えると、コードを特に強く信頼するかどうかはわかりませんが、少なくともわずかに動作すると予想していました! SharpZipLib を使用してみましたか?
zlibヘッダーをスキップして(最初の2バイト、 78 9C
)、次に。netに組み込まれている DeflateStream
は私のために機能しました。
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);
}
}
以下のコードは皆さんに役立つでしょう。オブジェクトをインスタンス化し、関数を使用します。
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();
}
}
サンプルコードをより詳しく見ると、通常の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();
}
}
最近、以前はphpを使用してIE7を含むさまざまなブラウザやプラットフォームにzlibしたドキュメントを提供するという不幸がありました。 (当時考えられていたように)ドキュメントがzlibされていてgzipされていないことがわかったら、 SharpZipLib は、.NET Framework v4で次のように( 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;
}
SharpZipLibから使用するクラスのサポートが必要な場合に備えて、ここに配置すると思います。