java GZIPInputStream 和 GZIPOutputStream 未按预期工作
java GZIPInputStream and GZIPOutputStream not working as expected
我正在尝试将一系列 Long
写入 GZIPOutputStream
,希望稍后解压这些数字。
当我尝试使用少量 Long
时,以下程序工作正常,但它会抛出许多 Long
的异常,例如 (10240)。
请参阅 运行 此代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GzipTest {
private static final String filename = "data.gz";
public static void main(String... args) throws Exception {
test(32); // OK
test(10240); // Why won't this work? (unexpected read: 6)
}
public static void test(int max) throws Exception {
System.out.println("testing with " + max);
FileOutputStream fos = new FileOutputStream(filename);
GZIPOutputStream gos = new GZIPOutputStream(fos, 4096);
long num = 10241000L;
for (int i = 0; i < max; ++i) {
gos.write(long2bytes(num + i));
}
gos.close();
fos.close();
GZIPInputStream gis = new GZIPInputStream(new FileInputStream(filename), 4096);
byte[] buf = new byte[Long.BYTES];
for (int i = 0; i < max; ++i) {
int nread = gis.read(buf);
if (nread != Long.BYTES) {
throw new RuntimeException("unexpected read: " + nread);
}
long value = bytes2long(buf);
if (value != num + i) {
throw new RuntimeException("unexpected value: " + value);
}
}
gis.close();
}
static byte[] long2bytes(long num) {
ByteBuffer buf = ByteBuffer.allocate(Long.BYTES);
buf.putLong(num);
return buf.array();
}
static long bytes2long(byte[] bytes) {
return ByteBuffer.wrap(bytes).getLong();
}
}
输出:
testing with 32
testing with 10240
Exception in thread "main" java.lang.RuntimeException: unexpected read: 6
at GzipTest.test(GzipTest.java:31)
at GzipTest.main(GzipTest.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
如果您按照 Peter Lawrey 的建议进行更改,代码可以正常工作:
try (DataInputStream in = new DataInputStream(new GZIPInputStream(new FileInputStream(filename), 4096))) {
byte[] buf = new byte[Long.BYTES];
for (int i = 0; i < max; ++i) {
in.readFully(buf);
long value = bytes2long(buf);
if (value != num + i) {
throw new RuntimeException("unexpected value: " + value);
}
}
}
或者您可以将所有内容简化为:
try (DataInputStream in = new DataInputStream(new GZIPInputStream(new FileInputStream(filename), 4096))) {
for (int i = 0; i < max; ++i) {
long value = in.readLong();
if (value != num + i) {
throw new RuntimeException("unexpected value: " + value);
}
}
}
我正在尝试将一系列 Long
写入 GZIPOutputStream
,希望稍后解压这些数字。
当我尝试使用少量 Long
时,以下程序工作正常,但它会抛出许多 Long
的异常,例如 (10240)。
请参阅 运行 此代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GzipTest {
private static final String filename = "data.gz";
public static void main(String... args) throws Exception {
test(32); // OK
test(10240); // Why won't this work? (unexpected read: 6)
}
public static void test(int max) throws Exception {
System.out.println("testing with " + max);
FileOutputStream fos = new FileOutputStream(filename);
GZIPOutputStream gos = new GZIPOutputStream(fos, 4096);
long num = 10241000L;
for (int i = 0; i < max; ++i) {
gos.write(long2bytes(num + i));
}
gos.close();
fos.close();
GZIPInputStream gis = new GZIPInputStream(new FileInputStream(filename), 4096);
byte[] buf = new byte[Long.BYTES];
for (int i = 0; i < max; ++i) {
int nread = gis.read(buf);
if (nread != Long.BYTES) {
throw new RuntimeException("unexpected read: " + nread);
}
long value = bytes2long(buf);
if (value != num + i) {
throw new RuntimeException("unexpected value: " + value);
}
}
gis.close();
}
static byte[] long2bytes(long num) {
ByteBuffer buf = ByteBuffer.allocate(Long.BYTES);
buf.putLong(num);
return buf.array();
}
static long bytes2long(byte[] bytes) {
return ByteBuffer.wrap(bytes).getLong();
}
}
输出:
testing with 32
testing with 10240
Exception in thread "main" java.lang.RuntimeException: unexpected read: 6
at GzipTest.test(GzipTest.java:31)
at GzipTest.main(GzipTest.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
如果您按照 Peter Lawrey 的建议进行更改,代码可以正常工作:
try (DataInputStream in = new DataInputStream(new GZIPInputStream(new FileInputStream(filename), 4096))) {
byte[] buf = new byte[Long.BYTES];
for (int i = 0; i < max; ++i) {
in.readFully(buf);
long value = bytes2long(buf);
if (value != num + i) {
throw new RuntimeException("unexpected value: " + value);
}
}
}
或者您可以将所有内容简化为:
try (DataInputStream in = new DataInputStream(new GZIPInputStream(new FileInputStream(filename), 4096))) {
for (int i = 0; i < max; ++i) {
long value = in.readLong();
if (value != num + i) {
throw new RuntimeException("unexpected value: " + value);
}
}
}