10

I just found there is no readUnsignedInt() method in the RandomAccessFile class. Why? Is there any workaround to read an unsigned int out from the file?

Edit:

I want to read an unsigned int from file and put it into a long space.

Edit2:

Cannot use readLong(). it will read 8 bytes not 4 bytes. the data in the file have unsigned ints in 4 bytes range.

Edit3:

Found answer here: http://www.petefreitag.com/item/183.cfm

Edit4:

how about if the data file is little-endian? we need to bits swap first?

5YrsLaterDBA
  • 29,380
  • 38
  • 121
  • 200
  • 3
    Java doesn't support unsigned integers. http://stackoverflow.com/questions/430346/why-doesnt-java-support-unsigned-ints – Swati May 20 '11 at 20:43
  • 1
    @Swati: Well, they could've done it like with `readUnsignedShort()` which reads 2 bytes and returns an int: Read 4 bytes and return a long. – musiKk May 20 '11 at 20:46
  • They could've also just implemented unsigned int, but what can you do. – Swati May 20 '11 at 20:51
  • Pete freitag's answer is rather long winded. There are any number of sorter, simpler solutions available in the JDK itself. – Peter Lawrey May 21 '11 at 09:10

4 Answers4

19

I'd do it like this:

long l = file.readInt() & 0xFFFFFFFFL;

The bit operation is necessary because the upcast will extend a negative sign.


Concerning the endianness. To the best of my knowledge all I/O in Java is done in big endian fashion. Of course, often it doesn't matter (byte arrays, UTF-8 encoding, etc. are not affected by endianness) but many methods of DataInput are. If your number is stored in little endian, you have to convert it yourself. The only facility in standard Java I know of that allows configuration of endianness is ByteBuffer via the order() method but then you open the gate to NIO and I don't have a lot of experience with that.

musiKk
  • 13,517
  • 4
  • 49
  • 81
3

Edited to remove readLong():

You could use readFully(byte[] b, int off, int len) and then convert to Long with the methods here: How to convert a byte array to its numeric value (Java)?

Community
  • 1
  • 1
Chris Morgan
  • 2,050
  • 16
  • 19
2

Because there is no unsigned int type in java? Why not readLong() ? You can readLong and then take first 32 bits.

Edit You can try

long value = Long.parseLong(Integer.toHexString(file.readInt()), 16);
Mikita Belahlazau
  • 14,587
  • 1
  • 35
  • 42
  • *Because there is no unsigned int type in java?* Well, there is actually a `readUnsignedByte`... – aioobe May 20 '11 at 20:47
  • And then use `seek()` to go 4 bytes back because `readLong()` consumes too many bytes? – musiKk May 20 '11 at 20:48
  • @aioobe, yes, sorry, didn't notice these methods. – Mikita Belahlazau May 20 '11 at 20:51
  • 2
    Nothing personal, I think both solutions are horrible. The first consumes too many bytes, the second creates a hex string and parses it?! Java is not a scripting language. Why does this answer have so many upvotes? – musiKk May 20 '11 at 20:58
  • @musiKk, it depends on how you measure 'beaty' of the code. If you need speed - yes, my solution is horrible. But if you don't care adout speed much, it is smaller solution than create long from array of bytes. Although I understand that if somebody use RandomAccessFile, he is likely need speed. – Mikita Belahlazau May 20 '11 at 21:05
  • @Nikita: Ok, I think I got a little carried away. Still, I think creating a temporary string that only gets parsed again should be avoided whenever possible. – musiKk May 20 '11 at 21:08
0

Depending on what you are doing with the int, you may not need to turn it into a long. You just need to be aware of the operations you are performing. After all its just 32-bits and you can treat it as signed or unsigned as you wish.

If you want to play with the ByteOrder, the simplest thing to do may be to use ByteBuffer which allows you to set a byte order. If your file is less than 2 GB, you can map the entire file into memory and access the ByteBuffer randomly.

Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075