CODEBLACK
CODEBLACK

Reputation: 1249

How to check for a null byte delimiter when reading from a binary file in Java?

I`m trying to improve my binary IO skills and thus am writing a simple utility that reads a mobi formatted ebook and prints the first 32 bytes in order to display the name of the book.

The Palm Database Format states that the first 32 bytes of the binary file contains the database/book name, and that this name is 0 terminated.

I am not sure how to check if the byte I read is null terminated.

File file = new File("ebook.mobi");
DataInputStream in = new DataInputStream(new FileInputStream(file));

int count = 1;
while(count++ <= 32){
    System.out.print((char)in.readByte());
}       
in.close();

In this case the output prints:

Program_or_Be_Programmed <--- this is immediately followed by a number of square symbols

I attempted to change the while loop to no avail:

while(count++ < 32 || in.readByte != 0)

I want to add some statement to stop the loop printing characters when it encounters a 0 byte.

How would I implement this?

Upvotes: 1

Views: 11511

Answers (2)

Ron
Ron

Reputation: 1508

This is the code you said you attempted:

while(count++ <= 32 || in.readByte != 0){
    System.out.print((char)in.readByte());
}       

The DataInputStream is being read twice, once in the while boolean check and again in the body.

Try:

byte b = 0;
while(++count < 32 && (b=in.readByte()) != 0){
    System.out.print((char)b);
} 

Note that ++count is less resource intensive than count++ since it does not create a duplicate.

To answer your question about null bytes: null in ascii (NUL), '\0' when displayed as a symbol, is represented by the value 0. It is the end of line (EOL) character and is appended to Strings automatically.

More specifically:

char c = '\0';
byte b = (byte) c; //b == 0

Upvotes: 1

Thilo
Thilo

Reputation: 262724

while(count++ < 32 || in.readByte != 0)

Since you want to stop when the byte is zero, it should be

while(count++ < 32 && in.readByte() != 0)

but you also need to store the byte somewhere if you want to use it in the loop body, because you can't call readByte() again (without advancing the stream).

I would do

 while(count++ <= 32){
     byte c = in.readByte();
     if (c == 0)
        break;
     System.out.print((char)c);

 }       

Upvotes: 1

Related Questions