【发布时间】:2013-07-25 18:49:03
【问题描述】:
我在读取 java 中的自定义文件时遇到了很多麻烦。 自定义文件格式只包含一个所谓的“魔术”字节数组、文件格式版本和一个 gzip 压缩的 json 字符串。
编写文件就像一个魅力 - 另一边的阅读并不像预期的那样工作。 当我尝试读取以下数据长度时,会抛出 EOFException。
我用十六进制编辑器检查了生成的文件,数据被正确保存。 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();
我真的希望有人能帮我解决我的问题(我已经尝试解决这个问题一整天了)!
问候
【问题讨论】:
-
您是否在尝试读取输出流之前刷新它?如果没有,那么您的 data.length 及其后面的数据可能只是卡在某个缓冲区中。
-
我没有刷新任何东西,你看到的代码就是我正在使用的完整代码。我尝试使用 in.reset() 但它只有“不支持标记/重置”IOException
-
很可能您没有写入您认为的所有数据,因为您没有正确关闭文件或没有刷新数据。除非没有更多可以读取的数据,否则您不会得到 EOF。
-
我什至尝试编写一个数据长度为 0 的文件(只有内容是 MAGIC、VERSION 和 0)——同样的事情。就像我说的,我用我的 HEX-Editor 多次检查了文件,数据被正确写入:(
-
让我们把 GZIP 排除在外:注释掉读/写实际数据的行(连同 GZIP 行),而不是写 data.length,只写一个数字(例如 42 ) 看看你能不能读到那个数字。另外,你清楚地展示给我们的代码不是你的完整程序;你能告诉我们什么叫读文件代码和写文件代码吗?它们只是一个方法中的块,还是两个方法,或者......?此外,即使您仍然遇到问题,dkatzel 认为您需要关闭流是正确的,因此请使用包含关闭的新版本更新上面的代码。
标签: java json file eof datainputstream