2011-12-19 24 views
1

我正在嘗試使用帶有ZLIB .NET庫的字典,但ZStream成員inflateSetDictionary始終返回Z_STREAM_ERROR。我已經跟蹤到這個子調用Inflate.inflateSetDictionary哪個測試是否(z.istate.mode == DICT0如何在ZLIB.NET中使用字典?

有誰知道如何使用這個庫的字典或知道任何好例子。我的代碼的簡化版本如下...

public class Form1 : System.Windows.Forms.Form 
{ 
    static private string sDictionary = "VALUE1,VALUE2,VALUE3"; 

    class GZOutputStream : ZOutputStream 
    { 
     public GZOutputStream(Stream in_Renamed) 
      : base(in_Renamed) 
     { 

      byte[] dictionary = System.Text.ASCIIEncoding.ASCII.GetBytes(sDictionary); 
      z.inflateSetDictionary(dictionary, dictionary.Length); 
     } 

     public GZOutputStream(Stream in_Renamed, int level) 
      : base(in_Renamed, level) 
     { 

      byte[] dictionary = System.Text.ASCIIEncoding.ASCII.GetBytes(sDictionary); 
      z.deflateSetDictionary(dictionary, dictionary.Length); 
     } 
    } 


    class GZInputStream : ZInputStream 
    { 
     public GZInputStream(Stream in_Renamed) 
      : base(in_Renamed) 
     { 

      byte[] dictionary = System.Text.ASCIIEncoding.ASCII.GetBytes(sDictionary); 
      z.inflateSetDictionary(dictionary, dictionary.Length); 
     } 

     public GZInputStream(Stream in_Renamed, int level) 
      : base(in_Renamed, level) 
     { 

      byte[] dictionary = System.Text.ASCIIEncoding.ASCII.GetBytes(sDictionary); 
      z.deflateSetDictionary(dictionary, dictionary.Length); 
     } 
    } 


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

    private void compressFile(string inFile, string outFile) 
    { 
     FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create); 
     GZOutputStream outZStream = new GZOutputStream(outFileStream, 1); // 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(); 
     } 
    } 


    private void decompressFile(string inFile, string outFile) 
    { 
     FileStream outFileStream = new FileStream(outFile, FileMode.Create); 
     GZOutputStream outZStream = new GZOutputStream(outFileStream); 
     FileStream inFileStream = new FileStream(inFile, FileMode.Open);    
     try 
     { 
      CopyStream(inFileStream, outZStream); 
     } 
     finally 
     { 
      outZStream.Close(); 
      outFileStream.Close(); 
      inFileStream.Close(); 
     } 
    } 

} 
+0

沒有答案買一個可能的黑客...嘗試將字典轉換爲列表...並嘗試序列化...還嘗試序列化字典中的項目...如果您的字典是字典<字符串,{ customeType}>也許錯誤信息是錯誤的,實際上是因爲它不能序列化字典的內容 – 2011-12-19 14:24:31

回答

0

雖然我沒有completley解決我的問題,我想分享我的進步......

當解壓縮數據流必須等到Z_NEED_DICT由充氣(..)函數返回,爲此我已經添加的代碼到ZLIB類ZInputStream和ZOutputStream以下部分來檢查從z.inflate返回的錯誤值...

  if (err == zlibConst.Z_NEED_DICT) 
      { 
       byte[] dictionary = System.Text.ASCIIEncoding.ASCII.GetBytes(sDictionary); 
       z.inflateSetDictionary(dictionary, dictionary.Length); 
       err = z.inflate(flush_Renamed_Field); 
      } 

Additionaly有似乎是跟隨s的錯誤從Inflate.inflate功能代碼撓度...

    case DICT4: 

        if (z.avail_in == 0) 
         return r; r = f; 

        z.avail_in--; z.total_in++; 
        z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked((int)0xff000000L); 
        z.istate.mode = DICT3; 
        goto case DICT3; 

在此代碼z.istate.need的值被設置爲一個值0xffffffffxx000000,這是不正確的頂部位應該是零例如0x00000000xx0000。

以下變動修正了這個問題..

z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L; 
1

我設法zlib壓縮與字典合作,開發基於DotNetZip(nugetgithub)。由於api調用既不需要明顯的,有據可查的文檔,也不需要簡短,因此我將封裝器放置在其自己的nuget包ZlibWithDictionary(nuget,github)中。

用法很簡單:

var compressed_byte_array = DeflateCompression.ZlibCompressWithDictionary(
    bytes_array_to_compress, 
    CompressionLevel.Default, 
    null /*use default window size in bits; possible values 9-15*/, 
    CompressionStrategy.Default, 
    byte_array_of_dictionary 
); 
var decompressed_byte_array = DeflateCompression.ZlibDecompressWithDictionary(
    compressed_byte_array, 
    byte_array_of_dictionary 
); 

如果你喜歡手動使用適當的zlib的API,您可以仔細閱讀the source for the DeflateCompression wrapper