开发者

C# DeflateStream vs Java DeflaterOutputStream

开发者 https://www.devze.com 2023-04-05 20:05 出处:网络
In Java, this works as expected: public static void testwrite(String filename) throws IOException { FileOutputStream fs = new FileOutputStream(new File(filename), false);

In Java, this works as expected:

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

The first method compresses 2000 chars in a 106 bytes file, the second reads it ok.

The equivalent in C# would seem to be

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

But it generates a file of 2636 bytes (l开发者_运维问答arger than the raw data, even though it has low entropy) and is not readable with the Java testread() method above. Any ideas?

Edited: The implementation is indeed not standard/portable (this bit of the docs: "an industry standard algorithm" seems a joke), and very crippled. Among other things, its behaviour changes radically if one writes the bytes one at a time or in blocks (which goes against the concept of a "stream"); if I change the above

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

by

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

the compression gets (slightly) reasonable. Shame.


Don't use DeflateStream on anything except plain ASCII text, because it uses statically defined, hardcoded Huffman trees built for plain ASCII text. See my prior answer for more detail, or just use SharpZipLib and forget it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号