[英]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。 <<
将第二批8位作为最高有效位左移。 byteNo * 8
可确保仅在两个字节中的第二个字节时才移位位。 读取两个字节之后, ampValue
现在将包含short
的样本值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.