0

Javaでカスタムファイルを読むのに苦労しています。カスタム ファイル形式は、いわゆる「マジック」バイト配列、ファイル形式バージョン、および gzip された 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();

誰かが私の問題を解決してくれることを本当に願っています(私はすでに一日中この問題を解決しようとしています)!

よろしく

4

1 に答える 1

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();
于 2013-07-25T19:30:34.630 に答える