我在使用C#.NET讀取壓縮的(放縮的)數據文件時遇到問題DeflateStream(..., CompressionMode.Decompress)
。該文件早先使用DeflateStream(..., CompressionMode.Compress)
編寫,似乎很好(我甚至可以使用Java程序對其進行解壓縮)。使用DeflateStream解壓縮數據文件
但是,調用輸入流的第一個Read()
來解壓縮/擴展壓縮數據返回長度爲零(文件結束)。
這裏的主要驅動力,這是用於壓縮和解壓的:
public void Main(...)
{
Stream inp;
Stream outp;
bool compr;
...
inp = new FileStream(inName, FileMode.Open, FileAccess.Read);
outp = new FileStream(outName, FileMode.Create, FileAccess.Write);
if (compr)
Compress(inp, outp);
else
Decompress(inp, outp);
inp.Close();
outp.Close();
}
下面是減壓的基本代碼,這就是失敗:
public long Decompress(Stream inp, Stream outp)
{
byte[] buf = new byte[BUF_SIZE];
long nBytes = 0;
// Decompress the contents of the input file
inp = new DeflateStream(inp, CompressionMode.Decompress);
for (;;)
{
int len;
// Read a data block from the input stream
len = inp.Read(buf, 0, buf.Length); //<<FAILS
if (len <= 0)
break;
// Write the data block to the decompressed output stream
outp.Write(buf, 0, len);
nBytes += len;
}
// Done
outp.Flush();
return nBytes;
}
呼叫標記FAILS
總是返回零。爲什麼?我知道這很簡單,但我只是沒有看到它。
下面是壓縮的基本代碼,它工作得很好,並幾乎完全一樣,名稱分別減壓方法交換:
public long Compress(Stream inp, Stream outp)
{
byte[] buf = new byte[BUF_SIZE];
long nBytes = 0;
// Compress the contents of the input file
outp = new DeflateStream(outp, CompressionMode.Compress);
for (;;)
{
int len;
// Read a data block from the input stream
len = inp.Read(buf, 0, buf.Length);
if (len <= 0)
break;
// Write the data block to the compressed output stream
outp.Write(buf, 0, len);
nBytes += len;
}
// Done
outp.Flush();
return nBytes;
}
解決
看到正確的解決方案後, ,構造語句應更改爲:
inp = new DeflateStream(inp, CompressionMode.Decompress, true);
它將底層輸入流開放,以下線路需要添加以下的inp.Flush()
電話:
inp.Close();
的Close()
調用強制deflater流刷新其內部緩衝區。 true
標誌阻止它關閉底層流,後面在Main()
後關閉。還應該對Compress()
方法進行相同的更改。
@LoadMaster另一種方法:BTW:當我跑了你的代碼,我沒有得到你所描述的相同的行爲,但它也沒有工作。在我的情況下,解壓縮似乎是成功的,但如果我將解壓縮的文件與原始文件進行比較,它們不匹配。解壓縮的文件比原來的缺少的字節小。 我們在DeflateStream上調用close()的更改也修復了這個問題。我懷疑行爲上的差異可能與我的測試文件的大小有關 - 也許它會丟失最後的N個字節,並且我的文件比較大(我的文件是364,391字節)。 – JMarsch 2009-10-07 15:55:14
Doh。當然,它在文檔中說有必要關閉deflater流以確保所有內部緩衝區都被正確刷新。我應該在Decompress()和Compress()方法中調用壓縮器/解壓縮器流上的'Close()',因爲它們直接控制壓縮器/解壓縮器流。 或者,我可以用'keepOpen'標誌打開'DeflaterStream'來保持底層輸入流的打開狀態。我仍然關閉deflater流,但之後我還要關閉底層文件流。我嘗試了這一點,它的工作原理。 – 2009-10-07 17:00:52