C # DeflateStream против Java DeflaterOutputStream - PullRequest
2 голосов
/ 20 сентября 2011

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

Первый метод сжимает 2000 символов в 106-байтовом файле, второй читает нормально.

Эквивалент в 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 Ответ

3 голосов
/ 20 сентября 2011

Не используйте DeflateStream ни с чем, кроме простого текста ASCII, потому что он использует статически определенные, жестко закодированные деревья Хаффмана, построенные для простого текста ASCII. См. мой предыдущий ответ для получения более подробной информации или просто используйте SharpZipLib и забудьте об этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...