2009-07-08 74 views
0

我正在嘗試從一個程序中讀取一個二進制文件,該程序將一個日誌(各種)寫入一個dat文件,我已經合理地使用了Java的格式。我加載它像這樣:嘗試從二進制文件中讀取非Java基元

DataInputStream in = new DataInputStream(new FileInputStream("file.dat")); 

System.out.println("Bytes skipped: " + in.skipBytes(4)); 

System.out.println(in.readLong()); 

的問題是從readLong()的價值是什麼,我期待不同,在十六車間我強調六角塊

BF02 0000 

,並報告說,它是一個有效的簽名短/長號碼 - 但是輸出與我所期望的非常不同。看看Java Docs,它聲明它的類只有64位(8字節),而其他來源顯示帶符號的長整數應該是32位 - 是否有辦法解決這個問題?

乾杯,

湯姆

回答

3

原始類型意味着在不同語言和不同平臺上的不同事物。 (例如,在C中,在某些平臺上長32位而在其他平臺上長64位並不罕見。

首先,您必須知道.dat文件中的類型以及字節順序(大/小端)。 然後將單個字節組裝成一個合適的java類型 如果.dat文件指定了一個32位有符號整數,那麼java中的一個int將是合適的 如果它是一個無符號的32位整數,那麼您可能需要使用長期在java中捕捉到所有可能的值,因爲Java沒有無符號類型

讀它如下,如果該文件中的整數是小端:

int i = (in.readByte()) | (in.readByte() << 8) | (in.readByte() << 16) | (in.readByte() << 24) 

,如果它是大端,做

int i = (in.readByte() << 24) | (in.readByte() << 16) | (in.readByte() << 8) | (in.readByte()) 

(我不記得大氣壓。在這裏java的促銷規則,你可能需要和他們& 0xff在位移之前產生一個int) 當然,你可以讀取一個字節數組並操作該數組,而不是分別調用in.readByte()如果你想。

+1

或整數。reverseBytes(),Long.reverseBytes()。至少他們是分類打字。 – akarnokd 2009-07-08 17:00:33

2

長在Java是總是 8個字節(64位)。不同的語言和平臺使用不同的術語。如果你想讀4個字節,讀一個int。

+3

只要它是一個大端int ... – 2009-07-08 16:31:58

0

如果您使用Preon,那麼您不必完成所有的移位和遮擋。在反映編碼數據結構的類中,只需將某個字段標記爲綁定數值即可,主要是它。

class EncodedDataStructure { 

    @BoundNumber 
    private long theLong; 

} 

如果你想只讀4個字節,但還是希望它是一個漫長的:

@BoundNumber(size="32") // Size is number of bits 
private long theLong; 

Or if you want to force it to be big or little endian: 

@BoundNumber(size="32", byteOrder=Endian.Big) 
private long theLong; 

...你看它像這樣:

Codec<EncodedDataStructure> codec = Codecs.create(EncodedDataStructure.class); 
EncodedDataStructure structure = Codecs.decode(codec, file); 
1

讀取數據時可以使用ByteBuffer,並使用order()方法更改字節順序。