簡體   English   中英

讀取Java中的字節

[英]Reading bytes in Java

我試圖了解以下代碼行的工作方式:

for (int i = 0; i < numSamples; i++) {
        short ampValue = 0;
        for (int byteNo = 0; byteNo < 2; byteNo++) {
            ampValue |= (short) ((data[pointer++] & 0xFF) << (byteNo * 8));
        }
        amplitudes[i] = ampValue;
    }

據我了解,這是以包含方式讀取2個字節(每個樣本2個字節),即ampValue由兩個字節讀取組成。 數據是實際的數據樣本(文件),並且指針不斷增加以讀取它直到最后一個樣本。 但是我不明白這部分:

"data[pointer++] & 0xFF) << (byteNo * 8)); "

另外,我想知道如果我想將它讀為double而不是short會有所不同嗎?

在Java中,所有字節均已簽名。 表達式(data[pointer++] & 0xFF)將帶符號的字節值轉換為帶有字節值(如果是無符號的)的int值。 然后,表達式<< (byteNo * 8)取決於byteNo的值將結果值左移零或八位。 整個表達式的值按位或ampValue分配。

這段代碼中似乎有一個錯誤。 在迭代之間, ampValue的值不會重置為零。 並且不使用amplitude 這些標識符是否應該相同?

看起來data []是字節數組。

data [pointer ++]為您提供[-128..127]范圍內的字節值。

0xFF是int常量,因此...

data [pointer ++]和0xFF將字節值提升為[-128..127]范圍內的int值。 然后,&運算符將未設置為0xFF的所有位清零(即,將零個高24位清零,僅保留低8位。

現在,該表達式的值將在[0..255]范圍內。

<<操作符將結果左移(byteNo * 8)位。 就是說,將值乘以2(byteNo * 8)的冪。 當byteNo == 0時,它將乘以2以乘以0(即,將乘以1)。 當byteNo == 1時,它將乘以2以乘以8(即乘以256)。

此循環從數組中的每對字節創建一個[0..65535](16位)范圍內的int,將每對的第一個成員作為低階字節,將第二個成員作為高階字節字節。

將ampValue聲明為double無效,因為| =運算符不適用於double,但是您可以將振幅[]數組聲明為雙amplitudes[i] = ampValue數組,並且賦值amplitudes[i] = ampValue將隱式將值提升為[0.0..65535.0]范圍內的雙精度值。


附加信息:不要忽略@KevinKrumwiede對示例中的錯誤的評論。

讓我們分解一下語句:

  • |=是按位或與和賦值運算符。 a |= b等效於a = a | b a = a | b
  • (short)int元素從data數組轉換為short
  • pointer++是后遞增操作。 pointer的值將被返回並使用,然后以這種方式每次訪問時立即增加-在這種情況下,這是有益的,因為外循環從連續data循環通過2字節樣本(通過內循環)緩沖區,因此保持遞增。
  • &是按位AND運算符, 0xFF是字節0b11111111的十六進制值(十進制255); 表達式data[pointer++] & 0xFF基本上是說,對於從data數組中檢索到的字節中的每一位,將其與1 在這種情況下,它將強制Java(默認情況下存儲帶符號的字節對象(即,從-128到127的十進制值))作為無符號字節(即從0到255的值)返回Java。
  • 由於樣本的長度為2個字節,因此需要使用左移位運算符<<將第二批8位作為最高有效位左移。 byteNo * 8可確保僅在兩個字節中的第二個字節時才移位位。

讀取兩個字節之后, ampValue現在將包含short的樣本值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM