我在读取java中的自定义文件时遇到了很多问题。自定义文件格式只是由一个所谓的"魔术"字节数组、文件格式版本和一个gzipped json字符串组成。
写文件就像一种魅力——在另一边阅读并没有达到预期效果。当我试图读取以下数据长度时,会抛出EOFException。
我用HEX编辑器检查了生成的文件,数据被正确保存。当DataInputStream尝试读取文件时,似乎出现了问题。
读取文件代码:
DataInputStream in = new DataInputStream(new FileInputStream(file));
// Check file header
byte[] b = new byte[MAGIC.length];
in.read(b);
if (!Arrays.equals(b, MAGIC)) {
throw new IOException("Invalid file format!");
}
short v = in.readShort();
if (v != VERSION) {
throw new IOException("Old file version!");
}
// Read data
int length = in.readInt(); // <----- Throws the EOFException
byte[] data = new byte[length];
in.read(data, 0, length);
// Decompress GZIP data
ByteArrayInputStream bytes = new ByteArrayInputStream(data);
Map<String, Object> map = mapper.readValue(new GZIPInputStream(bytes), new TypeReference<Map<String, Object>>() {}); // mapper is the the jackson OptionMapper
bytes.close();
写入文件代码:
DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
// File Header
out.write(MAGIC); // an 8 byte array (like new byte[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}) to identify the file format
out.writeShort(VERSION); // a short (like 1)
// GZIP that stuff
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(bytes);
mapper.writeValue(gzip, map);
gzip.close();
byte[] data = bytes.toByteArray();
out.writeInt(data.length);
out.write(data);
out.close();
我真的希望有人能帮我解决这个问题(我已经试了一整天了)!
问候
我认为您没有正确地关闭fileOutputStream和GZIPOutputStream。
GZIPOutputStream要求您在完成压缩数据的写入后对其调用close()
。这将要求您保留对GZIPOutputStream的引用。
以下是我认为的代码应该是
DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
// File Header
out.write(MAGIC); // an 8 byte array (like new byte[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}) to identify the file format
out.writeShort(VERSION); // a short (like 1)
// GZIP that stuff
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
GZIPOutputStream zippedStream =new GZIPOutputStream(bytes)
mapper.writeValue(zippedStream, /* my data */); // mapper is the Jackson ObjectMapper, my data is a Map<String, Object>
zippedStream.close();
byte[] data = bytes.toByteArray();
out.writeInt(data.length);
out.write(data);
out.close();