2013-07-25 83 views
0

我在閱讀java中的自定義文件時遇到了很多麻煩。 自定義文件格式只包含一個所謂的「魔術」字節數組,文件格式版本和gzip壓縮的json字符串。即使仍有數據,DataInputStream.readInt()也會返回EOFException

寫文件就像一個魅力 - 閱讀另一邊的作品並不像預期的那樣。 當我試圖讀取以下數據長度時,會引發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

你是不是想從中讀取數據之前,沖洗你的輸出流?如果不是的話,你的data.length和它後面的數據可能只是被卡在一個緩衝區中。 – Tim

+0

我不會沖洗任何東西,您看到的代碼是我正在使用的完整代碼。我試圖使用in.reset(),但它只讓我「不支持標記/重置」IOException – spaceemotion

+0

最有可能的是,你沒有寫出所有你認爲你的數據,因爲你沒有關閉文件正確或不沖洗數據。除非沒有更多可讀的數據,否則您將無法獲得EOF。 –

回答

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(); 
+0

問題仍然存在 - 從文件本身讀取data.length整數時拋出EOFException。但完成和關閉功能的好提示! – spaceemotion

相關問題