简体   繁体   English

读取Java中的字节

[英]Reading bytes in Java

I am trying to understand how the following line of code works: 我试图了解以下代码行的工作方式:

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;
    }

As far as I understand, this is reading 2 bytes (as 2 bytes per sample) in a inclusive manner, ie the ampValue is composed of two byte reads. 据我了解,这是以包含方式读取2个字节(每个样本2个字节),即ampValue由两个字节读取组成。 The data is the actual data sample (file) and the pointer is increasing to read it upto the last sample. 数据是实际的数据样本(文件),并且指针不断增加以读取它直到最后一个样本。 But I don't understand this part: 但是我不明白这部分:

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

Also, I am wondering whether it makes any difference if I want to read this as a double instead of short? 另外,我想知道如果我想将它读为double而不是short会有所不同吗?

In Java, all bytes are signed. 在Java中,所有字节均已签名。 The expression (data[pointer++] & 0xFF) converts the signed byte value to an int with the value of the byte if it were unsigned. 表达式(data[pointer++] & 0xFF)将带符号的字节值转换为带有字节值(如果是无符号的)的int值。 Then the expression << (byteNo * 8) left-shifts the resulting value by zero or eight bits depending on the value of byteNo . 然后,表达式<< (byteNo * 8)取决于byteNo的值将结果值左移零或八位。 The value of the whole expression is assigned with bitwise or to ampValue . 整个表达式的值按位或ampValue分配。

There appears to be a bug in this code. 这段代码中似乎有一个错误。 The value of ampValue is not reset to zero between iterations. 在迭代之间, ampValue的值不会重置为零。 And amplitude is not used. 并且不使用amplitude Are those identifiers supposed to be the same? 这些标识符是否应该相同?

Looks like data[] is the array of bytes. 看起来data []是字节数组。

data[pointer++] gives you a byte value in the range [-128..127]. data [pointer ++]为您提供[-128..127]范围内的字节值。

0xFF is an int contstant, so... 0xFF是int常量,因此...

data[pointer++] & 0xFF promotes the byte value to an int value in the range [-128..127]. data [pointer ++]和0xFF将字节值提升为[-128..127]范围内的int值。 Then the & operator zeroes out all of the bits that are not set in 0xFF (ie, it zeroes out the 24 upper bits, leaving only the low 8 bits. 然后,&运算符将未设置为0xFF的所有位清零(即,将零个高24位清零,仅保留低8位。

The value of that expression now will be in the range [0..255]. 现在,该表达式的值将在[0..255]范围内。

The << operator shifts the result to the left by (byteNo * 8) bits. <<操作符将结果左移(byteNo * 8)位。 That's the same as saying, it multiplies the value by 2 raised to the power of (byteNo * 8). 就是说,将值乘以2(byteNo * 8)的幂。 When byteNo==0, it will multiply by 2 to the power 0 (ie, it will multiply by 1). 当byteNo == 0时,它将乘以2以乘以0(即,将乘以1)。 When byteNo==1, it will multiply by 2 to the power 8 (ie, it will multiply by 256). 当byteNo == 1时,它将乘以2以乘以8(即乘以256)。

This loop is creating an int in the range [0..65535] (16 bits) from each pair of bytes in the array, taking the first member of each pair as the low-order byte and the second member as the high-order byte. 此循环从数组中的每对字节创建一个[0..65535](16位)范围内的int,将每对的第一个成员作为低阶字节,将第二个成员作为高阶字节字节。

It won't work to declare ampValue as double, because the |= operator will not work on a double, but you can declare the amplitudes[] array to be an array of double, and the assignment amplitudes[i] = ampValue will implicitly promote the value to a double value in the range [0.0..65535.0]. 将ampValue声明为double无效,因为| =运算符不适用于double,但是您可以将振幅[]数组声明为双amplitudes[i] = ampValue数组,并且赋值amplitudes[i] = ampValue将隐式将值提升为[0.0..65535.0]范围内的双精度值。


Additional info: Don't overlook @KevinKrumwiede's comment about a bug in the example. 附加信息:不要忽略@KevinKrumwiede对示例中的错误的评论。

Let's break down the statement: 让我们分解一下语句:

  • |= is the bitwise or and assignment operator. |=是按位或与和赋值运算符。 a |= b is equivalent to a = a | b a |= b等效于a = a | b a = a | b . a = a | b
  • (short) casts the int element from the data array to a short . (short)int元素从data数组转换为short
  • pointer++ is a post-increment operation. pointer++是后递增操作。 The value of pointer will be returned and used and then immediately incremented every single time it's accessed in this fashion - this is beneficial in this case because the outer-loop is cycling through 2-byte samples (via the inner loop) from the contiguous data buffer, so this keeps incrementing. pointer的值将被返回并使用,然后以这种方式每次访问时立即增加-在这种情况下,这是有益的,因为外循环从连续data循环通过2字节样本(通过内循环)缓冲区,因此保持递增。
  • & is the bitwise AND operator and 0xFF is the hexadecimal value for the byte 0b11111111 (255 in decimal); &是按位AND运算符, 0xFF是字节0b11111111的十六进制值(十进制255); the expression data[pointer++] & 0xFF is basically saying, for each bit in the byte retrieved from the data array, AND it with 1 . 表达式data[pointer++] & 0xFF基本上是说,对于从data数组中检索到的字节中的每一位,将其与1 In this context, it forces Java, which by default stores signed byte objects (ie values from -128 to 127 in decimal), to return the value as an unsigned byte (ie values from 0 to 255 decimal). 在这种情况下,它将强制Java(默认情况下存储带符号的字节对象(即,从-128到127的十进制值))作为无符号字节(即从0到255的值)返回Java。
  • Since your samples are 2 bytes long, you need to shift the second lot of 8 bits left, as the most significant bits, using the left bit-shift operator << . 由于样本的长度为2个字节,因此需要使用左移位运算符<<将第二批8位作为最高有效位左移。 The byteNo * 8 ensures that you're only shifting bits when it's the second of the two bytes. byteNo * 8可确保仅在两个字节中的第二个字节时才移位位。

After the two bytes have been read, ampValue will now contain the value of the sample as a short . 读取两个字节之后, ampValue现在将包含short的样本值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM