我想讀取4個字節,它是一個無符號的32位整數的小端編碼,並將該值賦值給Java int只需使用按位運算符就可以將一個無符號整數的4個小端順序字節分配給Java基元嗎?
(是的,實際上我會用'long',但是在這種情況下,我'知道'無符號值永遠不會這麼大,它會溢出一個有符號整數在補碼符號,它適合我的插圖使用一個int)。
有問題的4個字節編碼值 '216' little-endian的風格:
0xD8000000
,基本上我只需要下面的位模式塞進Java int的:
0x000000D8
的以下簡單的代碼應該做到這一點......併爲前三個'0x00'字節成功:
byte b1 = din.readByte();
byte b2 = din.readByte();
byte b3 = din.readByte();
byte b4 = din.readByte();
int s = 0;
s = s | b4;
s = (s << 8);
s = s | b3;
s = (s << 8);
s = s | b2;
s = (s << 8);
s = s | b1;
return s;
然而,它搞砸了在:
s = s | b1;
...因爲B1的位是1101 1000,這是二進制補碼負數(-40),因爲最顯著位是1 。當Java在評估位運算符或運算符|之前將b1擴展爲int時,-40被編碼爲0xFFFFFFD8,這固定了我們天真的假設,即加寬int的前3個字節將爲0。
所以我的策略擱淺。但是我應該怎麼做呢?甚至有可能使用原始操作符來解決這個問題(請給出解決方案),還是必須訴諸類庫? (我在正常的編碼中並沒有直接使用比特和字節,所以我缺少這種習慣用法,因爲它似乎應該是'每天'的代碼)。
至於類庫的方法,下面的代碼片段得到正確的結果:
ByteBuffer b = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).put((byte) 0xD8).put((byte) 0x00).put((byte) 0x00).put((byte) 0x00);
b.flip();
int s = b.getInt();
...這是罰款的可讀性,但使用8個的方法調用,我寧願免除。
謝謝! David。
得看那個標誌擴展名。 – dty 2010-09-30 16:43:28
啊,我在狩獵期間看過那種東西,卻沒有花時間去執行我腦海中的代碼。但現在你說出來了,這很有道理,我將不會被未來的簡單包裝嚇倒!謝謝。 – 2010-09-30 17:10:48