How to use Bufferedinputstream correctly?

Asked

Viewed 784 times

3

I am creating an application in which I need to read from a video file and transmit packets of data that can be read again in memory. I am using the Ogg video format, because it is open source and because I found it simpler to understand. I used the BufferedInputStream to read from the file, but since the first 28 bytes are header information I chose to use the method buffer.read(byte[]) as follows:

byte[] buffer = new byte[28];
FileInputStream in = new FileInputStream("/path/video.ogv");
BufferedInputStream buffStream = new BufferedInputStream(in);
buffStream(buffer);

Thus, I can read a sequence of bytes faster. When inspecting the element buffer in the eclipse debug, I noticed that values above 128 are negative, this, I believe, is due to the fact that the maximum number I can represent with 1 byte is 128. I know that the values are corrupted because when opening the file on https://hexed.it, i can visualize the correct value in hexadecimal. For example, the value that corresponds to B5 = 181(dec) is as -75. How can I use this method and bypass this data corruption?

Obs.: Using a video decoder that already does this transparently is not an option. It is necessary to be this way because I am developing a distributed application and the data packets will be destined to other computers.

1 answer

4


This is not data corruption. It’s an annoying Java language prank.

Most programming languages represent a byte as a number from 0 to 255, i.e., a no sign value (unsigned). For some reason, Java wanted to be different and decided that the byte has signal (Signed), and therefore it has values from -128 to 127.

In binary form, the relative values of the bits in the unsigned schema are 128 (most significant), 64, 32, 16, 8, 4, 2 and 1 (less significant). In Java, the first value is -128 instead of 128.

In this way, to convert a value in the range -128 to 127 to the range 0 to 255, you do this:

public static int tirarSinalDoByte(byte a) {
    return (a + 256) % 256;
}

Or this other implementation (more efficient, but a little less didactic):

public static int tirarSinalDoByte(byte a) {
    return a & 0xFF;
}

To convert back:

public static byte formarByte(int a) {
    if (tirarSinalDoByte(a) != a) throw new IllegalArgumentException();
    return (byte) a;
}

In this turn conversion, if you are sure that the value of the a is always on the right track or want to despise anything other than the last 8 bits if you are not, you can remove this if or just cast the byte directly without having to call a specific function to do so.

  • Thank you very much for the clarification.

  • @Rodrigobrito If this answer solved your problem and there was no doubt left, I ask you to mark it as accepted/correct by clicking below the vote number.

  • @Carlosheuberger Yes. Thank you for the suggestion. In fact, that’s exactly what I had put into the method formarByte.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.