How can I read a file as unsigned bytes in Java?

13,149

Solution 1

Well, Java doesn't have the concept of unsigned bytes... the byte type is always signed, with values from -128 to 127 inclusive. However, this will interoperate just fine with other systems which have worked with unsigned values for example, C# code writing a byte of "255" will produce a file where the same value is read as "-1" in Java. Just be careful, and you'll be okay.

EDIT: You can convert the signed byte to an int with the unsigned value very easily using a bitmask. For example:

byte b = -1; // Imagine this was read from the file
int i = b & 0xff;
System.out.println(i); // 255

Do all your arithmetic using int, and then cast back to byte when you need to write it out again.

You generally read binary data from from files using FileInputStream or possibly FileChannel.

It's hard to know what else you're looking for at the moment... if you can give more details in your question, we may be able to help you more.

Solution 2

With the unsigned API in Java 8 you have Byte.toUnsignedInt. That'll be a lot cleaner than manually casting and masking out.

To convert the int back to byte after messing with it of course you just need a cast (byte)value

Solution 3

If using a larger integer type internally is not a problem, just go with the easy solution, and add 128 to all integers before multiplying them. Instead of -128 to 127, you get 0 to 255. Addition is not difficult ;)

Also, remember that the arithmetic and bitwise operators in Java only returns integers, so:

byte a = 0;
byte b = 1;

byte c = a | b;

would give a compile time error since a | b returns an integer. You would have to to

byte c = (byte) a | b;

So I would suggest just adding 128 to all your numbers before you multiply them.

Solution 4

You wrote in a comment (please put such informations in the question - there is an edit link for this):

I need to be able to multiply the contents of a file by a constant. I was assuming that I can read the bytes into a BigInteger and then multiply, however since some of the bytes are negative I am ending up with 12 13 15 -12 etc and gets stuck.

If you want to use the whole file as a BigInteger, read it in a byte[], and give this array (as a whole) to the BigInteger-constructor.

/**
 * reads a file and converts the content to a BigInteger.
 * @param f the file name. The content is interpreted as
 *   big-endian base-256 number.
 * @param signed if true, interpret the file's content as two's complement
 *                  representation of a signed number.
 *               if false, interpret the file's content as a unsigned
 *                  (nonnegative) number.
 */
public static BigInteger fileToBigInteger(File f, boolean signed)
    throws IOException
{
    byte[] array = new byte[file.length()];
    InputStream in = new FileInputStream(file);
    int i = 0; int r;
    while((r = in.read(array, i, array.length - i) > 0) {
        i = i + r;
    }
    in.close();
    if(signed) {
        return new BigInteger(array);
    }
    else {
        return new BigInteger(1, array);
    }
}

Then you can multiply your BigInteger and save the result in a new file (using the toByteArray() method).

Of course, this very depends on the format of your file - my method assumes the file contains the result of the toByteArray() method, not some other format. If you have some other format, please add information about this to your question.

"I need to be able to multiply the contents of a file by a constant." seems quite a dubious goal - what do you really want to do?

Share:
13,149
Admin
Author by

Admin

Updated on July 29, 2022

Comments

  • Admin
    Admin almost 2 years

    How can I read a file to bytes in Java?

    It is important to note that all the bytes need to be positive, i.e. the negative range cannot be used.

    Can this be done in Java, and if yes, how?

    I need to be able to multiply the contents of a file by a constant. I was assuming that I can read the bytes into a BigInteger and then multiply, however since some of the bytes are negative I am ending up with 12 13 15 -12 etc and get stuck.

  • Admin
    Admin over 13 years
    I need to be able to multiply the contents of a file by a constant. I was assuming that I can read the bytes into a BigInteger and then multiply, however since some of the bytes are negative I am ending up with 12 13 15 -12 etc and gets stuck.
  • someguy
    someguy over 13 years
    @tyr Are you multiplying each byte individually, or are you constructing a BigInteger based on several bytes read? If it's the latter, I don't see why you want to convert the bytes to their unsigned representation.
  • Admin
    Admin over 13 years
    I am constructing a BigInteger based on bytes read yes. I am converting them because when I am feeding method with BigInteger "12-1213" an exception is being generated. java.lang.NumberFormatException: Illegal embedded minus sign
  • Admin
    Admin over 13 years
    the bytes read are a simple concatenation in the biginteger, one byte next to the other.
  • someguy
    someguy over 13 years
    @tyr Ahh, you're passing a String. I thought you meant you would be passing a byte array to construct the BigInteger. Sorry.
  • someguy
    someguy over 13 years
    Assuming he wants to convert from two's-complement to unsigned, that will not work. For instance -1 + 128 equals 127 not 255, as it should be. Also, casting back to a byte will change any value outside a byte's range.