Tyler
Tyler

Reputation: 43

how to read a byte from a text file as an actual byte in hex instead of characters?

Im really unsure how to phrase my question, but here is the situation.

I have data in a text file, for example: 0x7B 0x01 0x2C 0x00 0x00 0xEA these values are a hex representation of ASCII symbols. I need to read this data and be able to parse and translate accordingly.

My problem so far is that ive tried using a scanner via something like scan.getNextByte() and was directed towards the post: [using java.util.Scanner to read a file byte by byte]

After changing the file input format to a fileinputstream i found that while doing something like fis.read(), this is returning 48, the ascii value for the character 0 in 0x7B.

I am looking for a way to interpret the data being read in has hex so 0x7B will be equivalent to "{" in ASCII.

Hope this is clear enough to all,

Thanks,

Upvotes: 0

Views: 784

Answers (3)

m.сhug
m.сhug

Reputation: 11

If you need scalable solution, try to write your own InputStream

Basic example:

class ByteStringInputStream extends InputStream {

    private final InputStream inputStream;

    public ByteStringInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    private boolean isHexSymbol(char c) {
        return (c >= '0' && c <= '9')
                || (c >= 'A' && c <= 'F')
                || (c == 'x');
    }

    @Override
    public int read() throws IOException {

        try {
            int readed;
            char[] buffer = new char[4];
            int bufferIndex = 0;

            while ((readed = inputStream.read()) != -1 && bufferIndex < 4) {
                if (isHexSymbol((char) readed)) {
                    buffer[bufferIndex] = (char) readed;
                }
                bufferIndex++;
            }

            String stringBuffer = new String(buffer);

            if (!stringBuffer.matches("^0x[0-9A-F]{2}$")) {
                throw new NumberFormatException(stringBuffer);
            }

            return Integer.decode(stringBuffer);

        } catch (Exception ex) {
            inputStream.close();
            throw new IOException("<YOUR_EXCEPTION_TEXT_HERE>", ex);
        }
    }

}

Usage:

ByteStringInputStream bsis = new ByteStringInputStream(new BufferedInputStream(System.in));
//you can use any InputStream instead

while (true) {
    System.out.println(bsis.read());
}

Demo:

>0x7B 0x01 0x2C 0x00 0x00 0xEA
123
1
44
0
0
234

Upvotes: 1

VGR
VGR

Reputation: 44335

Since your bytes are delimited by spaces, you can just use a Scanner to read them:

try (Scanner scanner = new Scanner(Paths.get(filename))) {
    while (scanner.hasNext()) {
        int byteValue = Integer.decode(scanner.next());
        // Process byteValue ...
    }
}

I encourage you to read about the Integer.decode method and the Scanner class.

Upvotes: 1

Andrew Rueckert
Andrew Rueckert

Reputation: 5215

If you're in a position to use external libraries, the Apache Commons Codec library has a Hex utility class that can turn a character-array representation of hex bytes into a byte array:

final String hexChars = "0x48 0x45 0x4C 0x4C 0x4F";
// to get "48454C4C4F"
final String plainHexChars = hexChars.replaceAll("(0x| )", "");
final byte[] hexBytes = Hex.decodeHex(plainHexChars.toCharArray());
final String decodedBytes = new String(hexBytes, Charset.forName("UTF-8"));

Upvotes: -1

Related Questions