-1

I am reading bytes as follows:

        try(FileInputStream f = new FileInputStream("nameOfFile")){
            int readByte = 0;
            int mask =0b111;
            while((readByte=f.read())!=-1) {
                System.out.println(Integer.toBinaryString(readByte & mask));
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

However, when i try to obtain the 8 bits that forms the number, sometimes I get 7 bits or even more bits than 8. Can anyone help me with this problem? I want to get 8 bits so after that i can look at first 3 bits for example. I need that for returning the charset in this method.

I'll be very gratefull if you help me. I am looking forward to hearing from you soon.

Best regards, WaterKnight

WaterKnight
  • 197
  • 7
  • 2
    I'm afraid it's pretty unclear what you are trying to achieve. You can help us out and thereby make it much more likely that you will receive a useful answer by editing your question to include a [mcve]. – John Bollinger Oct 06 '18 at 15:25
  • 2
    What do you mean by "obtain the 8 bits"? Obtain where? You have the 8 bits right there in the `int` (along with 24 more bits). If you want to "look at first 3 bits", go on and look: `readByte & 0x07`. Or if you want to "look": [`Integer.toBinaryString(readByte)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#toBinaryString-int-) – Andreas Oct 06 '18 at 15:26
  • @JohnBollinger I updated my code , just Would like to look at 3first bits of the int and know if it follows some kind of pattern. – WaterKnight Oct 06 '18 at 15:31
  • `110` is a *decimal* number, equals to the *binary* number `0b1101110`, so `(byteLeido[0] >>> 5)==110` will never ever be true. Perhaps you meant `(byteLeido[0] >>> 5) == 0b110` or `(byteLeido[0] >>> 5) == 0x06` or `(byteLeido[0] >>> 5) == 6`? – Andreas Oct 06 '18 at 15:31
  • @Andreas thats why I am asking to try to look at pattern at 3 or 2 first bits of the int that goes between 0 and 255. – WaterKnight Oct 06 '18 at 15:33
  • Duplicate of [How to get 0-padded binary representation of an integer in java?](https://stackoverflow.com/q/4421400/5221149) – Andreas Oct 06 '18 at 15:51

2 Answers2

1

A byte is an 8-bit two's-complement signed number.

If you think a byte has values 0..255, then you are wrong. The 8 bits are -128..127, because bit 7 is the sign bit.

When you do bit-manipulation using operators like >>>, the byte is first widened to an int, which means that sign-extension is applied.

So, unsigned value 199 (example), is bits 11000111, which as a byte is value -57 aka 0xC7, and when sign-extended to an int becomes -57 aka 0xFFFFFFC7.

When you right-shift that by 5 (>>> 5), you get 0x07FFFFFE aka 134217726.

Since you're only interested in the lowest 3 bits of that value, you need to mask it: (val >>> 5) & 0x07, which will give you what you're looking for: 0x06 aka 0b110

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • I read that .read() of an input stream returned and int with values 0..255, so as this decimals values are a byte i would like to look into the 3 highest bits from the byte. In adittion, I tried your solution, System.out.println(Integer.toBinaryString((readByte >>> 5) & 0x07)); but in console I get lines with 3 bits, other ones with 2 bits and others with 1bit. – WaterKnight Oct 06 '18 at 15:54
  • @WaterKnight Did you not read my comment to you in the other answer? Or the link I provided in comment to your question? For your convenience, here both are: "You are getting 3 bits from all of the bytes read. Those are all 3-bit values, but, like any other formatted number, **leading zeroes have been removed**, so e.g. `11` means `011`, and `0` means `000`" and [How to get 0-padded binary representation of an integer in java?](https://stackoverflow.com/q/4421400/5221149) – Andreas Oct 06 '18 at 15:58
  • @Andres I just read your comment on the other answer and got it working as follows Integer.toBinaryString(byteLeido>>>5).equals("110"). Thank you very much. – WaterKnight Oct 06 '18 at 16:03
0

[0, 255] range implies that you use all the 8 bits for value, without leaving the most significant bit for the sign.

FileInputStream.read() reads a byte of data. The int return type allows to spot the difference between -1 data and -1 used to signal end of the stream. In practice read() return value won't be greater than 255.

If you want to look at the last 3 bits use a bit mask. You can use binary literal to define your mask:

int mask = 0b111;
int lastBits = readBytes & mask;
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
  • when I make this i get the next input throught console: 1001100. I am using System.out.println(Integer.toBinaryString(b)); for getting a look into the bits. – WaterKnight Oct 06 '18 at 15:26
  • @TheScientificMethod I missed the point of the question, but you are right! – Karol Dowbecki Oct 06 '18 at 15:35
  • when I make the things from you updated answer all I get is: 100 11 1 0 1 10 0 1 10 10 100 ANSI. So i am not getting 3 bits from all of the bytes readed. – WaterKnight Oct 06 '18 at 15:40
  • @WaterKnight Sure you are getting 3 bits from all of the bytes read. Those are all 3-bit values, but, like any other formatted number, leading zeroes have been removed, so e.g. `11` means `011`, and `0` means `000`. – Andreas Oct 06 '18 at 15:49