How to unpack a binary file in java?

3.2k views Asked by At

May somebody help me to know how can I do in java what I do in ruby with the code below.

The ruby code below uses unpack('H*')[0] to stores the complete binary file content in variable "var" in ASCII format.

IO.foreach(ARGV[0]){ |l| 

        var = l.unpack('H*')[0]

} if File.exists?(ARGV[0])

Update: Hi Aru. I've tested the way you say in the form below

byte[] bytes = Files.readAllBytes(testFile.toPath());
str = new String(bytes,StandardCharsets.UTF_8);
System.out.println(str); 

But when I print the content of variable "str", the printout shows only little squares, like is not decoding the content. I'd like to store in "str" the content of binary file in ASCII format.

Update #2: Hello Aru, I'm trying to store in array of bytes all the binary file's content but I don't know how to do it. It worked with "FileUtils.readFileToByteArray(myFile);" but this is an external library, is there a built in option to do it?

File myFile = new File("./Binaryfile");
byte[] binary = FileUtils.readFileToByteArray(myFile); //I have issues here to store in array of bytes all binary content
String hexString = DatatypeConverter.printHexBinary(binary);
System.out.println(hexString); 

Update #3:

Hello ursa and Aru, Thanks for your help. I've tried both of your solutions and works so fine, but seeing Files.readAllBytes() documentation it says that is not intended to handle big files and the binary file I want to analyse is more than 2GB :(. I see an option with your solutions, read chunk by chunk. The chunks inside the binary are separated by the sequence FF65, so is there a way to tweak your codes to only process one chunk at a time based on the chunk separator? If not, maybe with some external library.

Update #4: Hello, I'm trying to modify your code since I'd like to read variable size chunks based of value of "Var".

How can I set an offset to read the next chunk in your code?

I mean, - in first iteration read the first 1024, - In this step Var=500 - in 2d iteration read the next 1024 bytes, beginning from 1024 - Var = 1024-500 = 524 - In this step Var=712 - in 3rd iteration read the next 1024 bytes, beginning from 1548 - Var = 1548-712 = 836 - and so on

is there a method something like read(number of bytes, offset)?

2

There are 2 answers

5
ursa On BEST ANSWER

You can use commons-codec Hex class + commons-io FileUtils class:

byte[] binary = FileUtils.readFileToByteArray(new File("/Users/user/file.bin");
String hexEncoded = Hex.encodeHex(binary);

But if you just want to read content of TEXT file you can use:

String content = FileUtils.readFileToString(new File("/Users/user/file.txt", "ISO-8859-1");

With JRE 7 you can use standard classes:

public static void main(String[] args) throws Exception {
    Path path = Paths.get("path/to/file");
    byte[] data = Files.readAllBytes(path);

    char[] hexArray = "0123456789ABCDEF".toCharArray();
    char[] hexChars = new char[data.length * 2];
    for ( int j = 0; j < data.length; j++ ) {
        int v = data[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    System.out.println(new String(hexChars));
}
1
Steffen On

This should do what you want:

try {
    File inputFile = new File("someFile");
    byte inputBytes[] = Files.readAllBytes(inputFile.toPath());
    String hexCode = DatatypeConverter.printHexBinary(inputBytes);
    System.out.println(hexCode);
} catch (IOException e) {
    System.err.println("Couldn't read file: " + e);
}

If you don't want to read the entire file at once, you can do so as well. You'll need an InputStream of some sort.

File inputFile = new File("C:\\Windows\\explorer.exe");
try (InputStream input = new FileInputStream(inputFile)) {
    byte inputBytes[] = new byte[1024];
    int readBytes;
    // Read until all bytes were read
    while ((readBytes = input.read(inputBytes)) != -1) {
        System.out.printf("%4d bytes were read.\n", readBytes);
        System.out.println(DatatypeConverter.printHexBinary(inputBytes));
    }
} catch (FileNotFoundException ex) {
    System.err.println("Couldn't read file: " + ex);
} catch (IOException ex) {
    System.err.println("Error while reading file: " + ex);
}