2011-05-20 13 views
10

Właśnie znalazłem, że nie ma metody readUnsignedInt() w klasie RandomAccessFile. Czemu? Czy istnieje sposób obejścia odczytu niepodpisanego int z pliku?Dlaczego nie ma wartości readUnsignedInt w klasie RandomAccessFile?

Edit:

Chcę przeczytać unsigned int z pliku i umieścić go w długiej przestrzeni.

Edit2:

Nie można użyć readLong(). odczyta 8 bajtów, a nie 4 bajty. dane w pliku mają unsigned ints w zakresie 4 bajtów.

Edit3:

Znaleziono odpowiedź tutaj: http://www.petefreitag.com/item/183.cfm

Edit4:

jak około jeśli plik danych jest little-endian? musimy najpierw wymienić bity?

+3

Java nie obsługuje liczb całkowitych bez znaku. http://stackoverflow.com/questions/430346/why-doesnt-java-support-unsigned-ints – Swati

+1

@Swati: Cóż, mogliby zrobić to tak jak z 'readUnsigned Short()', który czyta 2 bajty i zwraca int : Przeczytaj 4 bajty i zwróć długi. – musiKk

+0

Mogli również zaimplementować niepodpisaną int, ale co można zrobić. – Swati

Odpowiedz

19

Zrobiłbym to tak:

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

Obsługa bitu jest konieczna, ponieważ upcast spowoduje rozszerzenie znaku ujemnego.


Dotyczy endianness. Zgodnie z moją wiedzą wszystkie operacje wejścia-wyjścia w Javie wykonywane są w stylu big endian. Oczywiście, często nie ma to znaczenia (tablice bajtowe, kodowanie UTF-8 itp. Nie mają wpływu na endianię), ale wiele metod jest takich, jak DataInput. Jeśli twój numer jest przechowywany w małym endianie, musisz go sam przekonwertować. Jedynym obiektem w standardowej Javie, jaki znam, który pozwala na konfigurację endianness jest ByteBuffer za pomocą metody order(), ale potem otwierasz bramę do NIO i nie mam z tym dużego doświadczenia.

+1

+1 dobra sugestia! – aioobe

+1

Tak, to lepsze rozwiązanie :) –

+0

Zauważ, że bez "L" na końcu 0xFFFFFFFF to rozwiązanie nie zadziała, bez L, jeśli twój numer jest ujemny, twoje długie będzie również ujemne –

2

Ponieważ w java nie ma typu int bez podpisu? Dlaczego nie readLong()? Możesz odczytać Long, a następnie podjąć pierwsze 32 bity.

Edit Można spróbować

long value = Long.parseLong(Integer.toHexString(file.readInt()), 16); 
+0

* Ponieważ w java nie ma typu int bez podpisu? * Cóż, faktycznie istnieje 'readUnsignedByte' ... – aioobe

+0

A następnie użyj' seek() ', aby przejść 4 bajty do tyłu, ponieważ' readLong() 'zużywa zbyt wiele bajtów? – musiKk

+0

@aioobe, tak, przepraszam, nie zauważyłem tych metod. –

3

edytowane usunąć readLong():

Można użyć readFully(byte[] b, int off, int len) a następnie przekonwertować do Long z metodami tutaj: How to convert a byte array to its numeric value (Java)?

+1

To zje zbyt wiele bajtów, nie? – aioobe

+0

Nie pomoże to, jeśli liczba w pliku ma 4 bajty. 'readLong()' czyta 8 bajtów. – musiKk

+0

Prawda, można użyć 'readFully()', a następnie przekonwertować. –

0

W zależności od tego, co robisz z int, może nie być konieczne przekształcenie go w długi. Musisz tylko wiedzieć, jakie operacje wykonujesz. Przecież to tylko 32-bitowe i możesz traktować to jako podpisane lub niepodpisane, jak chcesz.

Jeśli chcesz grać z ByteOrder, najprostszą rzeczą do zrobienia może być użycie ByteBuffer, który pozwala ustawić kolejność bajtów. Jeśli twój plik ma mniej niż 2 GB, możesz zmapować cały plik do pamięci i losowo uzyskać dostęp do ByteBuffer.

Powiązane problemy