C#DeflateStream与Java DeflaterOutputStream

时间:2011-09-20 00:27:25

标签: c# java .net compression

在Java中,这可以按预期工作:

  public static void testwrite(String filename) throws IOException {
    FileOutputStream fs = new FileOutputStream(new File(filename), false);
    DeflaterOutputStream fs2 = new DeflaterOutputStream(fs, new Deflater(3));
    for (int i = 0; i < 50; i++)
      for (int j = 0; j < 40; j++)
        fs2.write((byte) (i + 0x30));
    fs2.close();
  }

  public static void testread(String filename) throws IOException {
    FileInputStream fs = new FileInputStream(new File(filename));
    InflaterInputStream fs2 = new InflaterInputStream(fs);
    int c, n = 0;
    while ((c = fs2.read()) >= 0) {
      System.out.print((char) c);
      if (n++ % 40 == 0)  System.out.println("");
    }
    fs2.close();
  }

第一种方法在一个106字节的文件中压缩2000个字符,第二种方法将其读成确定。

C#中的等价物似乎是

private static void testwritecs(String filename) {
    FileStream fs = new FileStream(filename, FileMode.OpenOrCreate);
    DeflateStream fs2 = new DeflateStream(fs,CompressionMode.Compress,false);
    for (int i = 0; i < 50; i++)   {
        for(int j = 0; j < 40; j++)
                fs2.WriteByte((byte)(i+0x30));
    }
    fs2.Flush();
    fs2.Close();
}

但它生成一个2636字节的文件(大于原始数据,即使它具有低熵),并且上面的Java testread()方法无法读取。有什么想法吗?

已编辑:实现确实不是标准/可移植的(docs的这一点:“行业标准算法”似乎是一个笑话),并且非常残缺。除其他外,如果一次一个地写入一个字节或者以块形式写入字节(这违背了“流”的概念),它的行为会发生根本变化;如果我改变上面的

for(int j = 0; j < 40; j++)
   fs2.WriteByte((byte)(i+0x30));

通过

byte[] buf = new byte{}[40;
for(int j = 0; j < 40; j++)
   buf[j]=(byte)(i+0x30));
fs2.Write(buf,0,buf.Length);

压缩得到(略微)合理。羞。

1 个答案:

答案 0 :(得分:3)

除了纯ASCII文本之外,不要使用DeflateStream,因为它使用 为纯ASCII文本构建的静态定义的硬编码霍夫曼树。有关详细信息,请参阅my prior answer,或者只使用SharpZipLib并忘记它。