繁体   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