Java program to detect the Java class File Format magic number, in a given file Description:

I wrote a Java program that checks whether the content of the given file begins with the Java class File Format magic number 0xCAFEBABE, in big-endian byte order.

It prints a success message if:


The first 4 bytes match the magic number


It prints an error message if:


The file doesn't exist or cannot be read
The file contains less than 4 bytes
The first 4 bytes don't match the magic number


It prints a usage message if:


A file is not given as input


Code:

import java.io.*;

public class Magic {

    public static void main(String[] args) {
        if (args.length &lt; 1) {
            System.out.println("Usage: java Magic &lt;FILE&gt;");
            return;
        }

        try {
            if (isMagicPresent(args[0])) {
                System.out.println(String.format("'%s' contains the magic number.", args[0]));
            } else {
                System.out.println(String.format("'%s' doesn't contain the magic number.", args[0]));
            }
        } catch (IOException ex) {
            System.err.println(ex.getMessage());
        }
    }

    private static boolean isMagicPresent(String file) throws IOException {
        try (InputStream instream = new FileInputStream(file)) {
            byte[] bytes = new byte[4];
            int readCount = instream.read(bytes);

            if (readCount == 4) {
                return Byte.toUnsignedInt(bytes[0]) == 0xCA &amp;&amp;
                        Byte.toUnsignedInt(bytes[1]) == 0xFE &amp;&amp;
                        Byte.toUnsignedInt(bytes[2]) == 0xBA &amp;&amp;
                        Byte.toUnsignedInt(bytes[3]) == 0xBE;
            }
        }
        return false;
    }

}



Question:

How can I improve the above code in terms of:


Readability
Performance
Boundary case and error handling
Interface

For clarity, isMagicPresent() should accept a java.io.File (or java.nio.file.Path) to emphasize that the argument is a path and not the contents of a file.

The default constructor should be suppressed.

Implementation

To read a big-endian int, use DataInputStream.readInt().  Then you can compare the magic number to 0xCAFEBABE rather than four bytes.

Driver

I recommend returning a non-zero exit code to indicate that an error has occurred.

When no argument is given, the error message should go to System.err.  (If you supported a -h or --help option, then its output should go to System.out, because that would be the requested output.)

Instead of System.out.println(String.format(…)), you should just call System.out.format(…).  Here, I've chosen to combine both cases into one print statement, but you don't have to.

Suggested implementation

import java.io.*;

public class Magic {
    private Magic() {}

    public static boolean isMagicPresent(File f) throws IOException {
        try (InputStream inStream = new FileInputStream(f);
             DataInputStream dataInStream = new DataInputStream(inStream)) {
            return dataInStream.readInt() == 0xCAFEBABE;
        }
    }

    public static void main(String[] args) {
        if (args.length &lt; 1) {
            System.err.println("Usage: java Magic &lt;FILE&gt;");
            System.exit(1);
        }

        File f = new File(args[0]);
        try {
            System.out.format(
                "'%s' %s the magic number.%n",
                f,
                isMagicPresent(f) ? "contains" : "doesn't contain"
            );
        } catch (IOException ex) {
            System.err.println(ex.getMessage());
            System.exit(1);
        }
    }
}