gzip
is documented to support concatenation of compressed files:
$ echo hello >hhh
$ echo world >www
$ cat hhh www
hello
world
$ echo hello | gzip >hhhh
$ echo world | gzip >wwww
$ cat hhhh wwww | gunzip
hello
world
I can create a concatenated file with GZIPOutputStream
, but unfortunately GZIPInputStream
reads only the first portion of data (gunzip
run from the command line reads all.)
I'm seeing this on both Android 4.1.2 and 4.4.2.
How do I read the whole file from Java?
UPDATE:
An example demonstrating the bug (the host version):
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
class GZTest {
static void append(File f, String s) {
try {
FileOutputStream fos = new FileOutputStream(f, true);
//FileOutputStream gzos = fos;
GZIPOutputStream gzos = new GZIPOutputStream(fos);
gzos.write(s.getBytes("UTF-8"));
gzos.close(); // TODO: do it finally{}
fos.close(); // TODO: do it finally{}
} catch (IOException e) {
e.printStackTrace();
}
}
static String readAll(File f) {
try {
FileInputStream fis = new FileInputStream(f);
//FileInputStream gzis = fis;
GZIPInputStream gzis = new GZIPInputStream(fis);
byte[] buf = new byte[4096];
int len = gzis.read(buf);
gzis.close(); // TODO: do it finally{}
fis.close(); // TODO: do it finally{}
return new String(Arrays.copyOf(buf, len), "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public class A {
public static void main(String[] args) {
System.out.println("~~~");
File f = new File("x.y");
f.delete();
GZTest.append(f, "Hello, ");
GZTest.append(f, "world!\n");
System.out.println(GZTest.readAll(f));
}
}
Running it:
$ javac A.java
$ java A
~~~
Hello,
$ gunzip <x.y
Hello, world!
UPDATE2
It looks like this is the bug JDK-2192186, reported to be fixed on 2010-08-03. Nevertheless, the bug is here now.