即使仍有数据,DataInputStream.readInt()也会返回EOFException

时间:2013-07-25 18:49:04

标签: java json file eof datainputstream

我在java中读取自定义文件时遇到了很多麻烦。 自定义文件格式只包含一个所谓的“魔术”字节数组,文件格式版本和gzipped json-string。

编写文件就像一个魅力 - 另一方面的阅读工作并不像预期的那样。 当我尝试读取以下数据长度时,会抛出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();

我真的希望有人可以帮我解决我的问题(我一整天都试图解决这个问题)!

此致

1 个答案:

答案 0 :(得分:0)

我认为您没有正确关闭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();