在Java中读取字节

时间:2014-08-24 18:31:11

标签: java type-conversion

我试图了解以下代码行的工作原理:

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)); "

另外,我想知道如果我想把它读成双倍而不是短片,是否有任何区别?

3 个答案:

答案 0 :(得分:0)

在Java中,所有字节都是有符号的。表达式(data[pointer++] & 0xFF)将带符号的字节值转换为带有字节值的int(如果它是无符号的)。然后,表达式<< (byteNo * 8)将结果值左移0或8位,具体取决于byteNo的值。整个表达式的值按位或ampValue分配。

此代码中似乎存在错误。迭代之间ampValue的值不会重置为零。并且未使用amplitude。这些标识符是否应该相同?

答案 1 :(得分:0)

看起来data []是字节数组。

data [pointer ++]为您提供[-128..127]范围内的字节值。

0xFF是一个int contstant,所以......

数据[指针++]&amp; 0xFF将字节值提升为[-128..127]范围内的int值。然后&amp;运算符将所有未在0xFF中设置的位清零(即,它将24位高位清零,只留下低8位。

该表达式的值现在将在[0..255]范围内。

&lt;&lt;运算符将结果向左移动(byteNo * 8)位。这与说法相同,它将值乘以2乘以(byteNo * 8)的幂。当byteNo == 0时,它将乘以2到幂0(即,它将乘以1)。当byteNo == 1时,它将乘以2到幂8(即它将乘以256)。

此循环在数组中的每对字节的[0..65535](16位)范围内创建一个int,将每对中的第一个成员作为低位字节,将第二个成员作为高阶字节。

将ampValue声明为double是不行的,因为| =运算符不能用于double,但是你可以将amplitudeitude []数组声明为double的数组,并赋值{{1将隐式地将值提升为[0.0..65535.0]范围内的double值。


其他信息:不要忽视@ KevinKrumwiede对该示例中的错误的评论。

答案 2 :(得分:0)

让我们分解声明:

  • |=是按位或赋值运算符。 a |= b相当于a = a | b
  • (short)int数组中的data元素投射到short
  • pointer++是一个增量后操作。 pointer的值将被返回并使用,然后每次以这种方式访问​​时立即递增 - 这在这种情况下是有益的,因为外循环循环通过2字节样本(通过内循环)来自连续的data缓冲区,因此这会不断增加。
  • &是按位AND运算符,0xFF是字节0b11111111的十六进制值(十进制为255);表达式data[pointer++] & 0xFF基本上是对于从data数组中检索到的字节中的每个位,以及1。在此上下文中,它强制Java,默认情况下存储 signed 字节对象(即十进制中-128到127的值),以将值作为 unsigned 字节返回(即0到255之间的值。)
  • 由于您的样本长度为2个字节,因此您需要使用左移位运算符<<将第二批8位左移,作为最高有效位。 byteNo * 8确保只有当它是两个字节中的第二个时才会移位。

在读取了两个字节后,ampValue现在将样本的值包含为short

相关问题