В 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);
сжатие становится (немного) разумным. Позор.