DataInputStream.readInt() stimmt nicht?

  • 8 Antworten
  • Letztes Antwortdatum
Murdock1

Murdock1

Ambitioniertes Mitglied
7
Hi,

ich versuche gerade mit DataInputStream.readInt() eine 32bit Integer auszulesen, bekomme aber nicht den Wert den ich möchte. Es sollte 2000({0xD0, 0x7, 0x0, 0x0}) rauskommen, kommt aber -804847616. Wie geht das richtig?

Code:
    public String GetVersionString(String filepath, int headerPosition){
        File file = new File(filepath);
        byte[] bytes = new byte[8];         
        BufferedInputStream buf;
        try {
            buf = new BufferedInputStream(new FileInputStream(file));
            DataInputStream dat = new DataInputStream(buf);
            dat.skip(headerPosition);
            dat.read(bytes);    
            Log.i("app", "preamble:: " + new String(bytes, "UTF-8"));
            int x = dat.readInt();
            Log.i("app", "version:: " + String.valueOf(x));
            dat.close();    
            buf.close();
            return String.valueOf(x);            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }        
        return "";
    }
 
das wollte cih auch schon sagen da es im big endian ausgewertet wird aber cih hab dann ein paar berechnungen an gestellt und irgendwie kam ich nciht auf seine -804847616 dabei
könnte auch sein dass er die headerposition falsch angegeben hat und so werden falsche bytes ausgelen wer weiß...

Der ursprüngliche Beitrag von 07:34 Uhr wurde um 07:40 Uhr ergänzt:

also seine zahl 2000 wäre ja 0b 0111 1101

die im big endian ausgelesene zahl wäre aber
0b 1011 1110 0000 0000 0000 0000 0000 0000 = -1040187393
 
Du könntest z.B. so eine Methode verwenden: java - Converting Little Endian to Big Endian - Stack Overflow.

Vielleicht gibts auch sauberere Lösungen...

Jaiel schrieb:
also seine zahl 2000 wäre ja 0b 0111 1101

die im big endian ausgelesene zahl wäre aber
0b 1011 1110 0000 0000 0000 0000 0000 0000 = -1040187393

0x000007D0 (Dezimal: 2000) wird zu 0xD0070000 (Dezimal: 3490119680). Das ist zu gross für einen INT, deshalb gibts einen Overflow und wird zu -804847616
 
  • Danke
Reaktionen: Murdock1
ah genau da lag dann mein Fehler ich hab mcih dann über diese schreibweise gewundert:

FFFFFFFFD0070000 aber ich hab grad gemerkt dass mein taschenrechner auf 64 bit seht
 
Moin,

ja es war die ByteReihenfolge, mit Integer.reverseBytes() bekomme ich den gewollten Wert. Hatte das mit der selben Datei in .net gemacht, da hatte die BitConverter-Klasse das richtig gemacht(?evtl. automatisch erkannt?). Um dem vorzubeugen, wie erkenne ich(Codeseitig) ob eine Datei nun Big- oder Low-Endian ist? Java hat dafür doch bestimmt was fertiges.
 
Zuletzt bearbeitet:
Kann man nciht wenn man nicht jeder Datei kontrollbytes mitschickt die an der richtigen stelle stehen müssen.
 
  • Danke
Reaktionen: Murdock1
OK, schade. Aber da bei APE-Tags nur 2 Versionen in Frage kommen, (1000=v1,2000=v2), bekomme ich beim verkehrten lesen durch den Overflow negative Zahlen, damit kann ich dann hier "Fehler" abfangen, bzw. zwischen Big- und Low-Endian unterscheiden. Natürlich auch durch die Position der beiden 0-Bytes.
 
Zuletzt bearbeitet:
Murdock1 schrieb:
wie erkenne ich(Codeseitig) ob eine Datei nun Big- oder Low-Endian ist? Java hat dafür doch bestimmt was fertiges.

Dass kann nicht allgemein ohne Kenntnis des Inhaltes erkannt werden. Beispiel: Eine Datei enthält nur die 4 bytes 0x00, 0x00, 0x00, 0x01. Das kann entweder 1(0x00000001) oder 16777216(0x01000000) sein. Nur wenn du weisst, dass die Zahl <3000 sein muss, kannst du die byteorder ermitteln.

ADD: sehe gerade, dass du das ja schon selbt erkannt hast
 
Zurück
Oben Unten