Ich frage, weil ich einen Byte-Stream von einem C-Prozess an Java sende. Auf der C-Seite hat die 32-Bit-Ganzzahl das LSB als erstes Byte und das MSB als 4. Byte.
Meine Frage lautet also: Was ist auf der Java-Seite Endian auf der Java-Seite, wenn wir das vom C-Prozess gesendete Byte lesen ?
Eine Folgefrage: Wenn der Endian auf der Java-Seite nicht mit dem gesendeten übereinstimmt, wie kann ich zwischen ihnen konvertieren?
java
endianness
hhafez
quelle
quelle
Antworten:
Verwenden Sie die Netzwerkbyte-Reihenfolge (Big Endian), die ohnehin mit Java identisch ist. Siehe man htons für die verschiedenen Übersetzer in C.
quelle
Ich bin hier über Google gestolpert und habe meine Antwort bekommen, dass Java Big Endian ist .
Beim Lesen der Antworten möchte ich darauf hinweisen, dass Bytes tatsächlich eine Endian-Reihenfolge haben, obwohl Sie, wenn Sie sich nur mit „Mainstream“ -Mikroprozessoren befasst haben, diese wahrscheinlich nie als Intel, Motorola und Zilog kennengelernt haben waren sich über die Verschiebungsrichtung ihrer UART-Chips einig und dass MSB eines Bytes
2**7
und LSB2**0
in ihren CPUs sein würden (ich habe die FORTRAN-Power-Notation verwendet, um zu betonen, wie alt dieses Zeug ist :)).Ich bin vor mehr als 20 Jahren auf dieses Problem mit einigen seriellen Downlink-Daten von Space Shuttle-Bits gestoßen, als wir eine 10.000-Dollar-Schnittstellenhardware durch einen Mac-Computer ersetzt haben. Es gibt einen NASA Tech Brief, der vor langer Zeit darüber veröffentlicht wurde. Ich habe einfach eine Nachschlagetabelle mit 256 Elementen verwendet, wobei die Bits umgekehrt (
table[0x01]=0x80
usw.) waren, nachdem jedes Byte aus dem Bitstrom verschoben wurde.quelle
In Java gibt es keine vorzeichenlosen Ganzzahlen. Alle ganzen Zahlen sind signiert und in Big Endian.
Es hört sich so an, als würden Sie LSB als am wenigsten signifikantes Bit verwenden, oder? LSB steht normalerweise für das niedrigstwertige Byte. Endianness basiert nicht auf Bits, sondern auf Bytes.
So konvertieren Sie ein vorzeichenloses Byte in eine Java-Ganzzahl:
So konvertieren Sie von vorzeichenlosem 32-Bit-Little-Endian in Byte [] nach Java Long (von oben, nicht getestet):
quelle
Es gibt keine Möglichkeit, dies in Java zu beeinflussen, da es keine (direkte Nicht-API-) Möglichkeit gibt, einige Bytes direkt in ein Int in Java abzubilden.
Jede API, die dies oder ähnliches tut, definiert das Verhalten ziemlich genau, daher sollten Sie die Dokumentation dieser API nachschlagen.
quelle
Ich würde die Bytes einzeln lesen und sie zu einem langen Wert kombinieren . Auf diese Weise steuern Sie die Endianness und der Kommunikationsprozess ist transparent.
quelle
Wenn es zu dem von Ihnen verwendeten Protokoll passt, sollten Sie einen DataInputStream verwenden, bei dem das Verhalten sehr gut definiert ist .
quelle
Java ist 'Big-Endian' wie oben erwähnt. Das bedeutet, dass sich das MSB eines int links befindet, wenn Sie den Speicher untersuchen (zumindest auf einer Intel-CPU). Das Vorzeichenbit befindet sich auch im MSB für alle Java-Integer-Typen.
Das Lesen einer 4-Byte-Ganzzahl ohne Vorzeichen aus einer Binärdatei, die von einem Little-Endian-System gespeichert wird, erfordert in Java einige Anpassungen. ReadInt () von DataInputStream erwartet das Big-Endian-Format.
Hier ist ein Beispiel, das einen vorzeichenlosen 4-Byte-Wert (wie von HexEdit als 01 00 00 00 angezeigt) in eine Ganzzahl mit dem Wert 1 liest:
quelle
Java Force in der Tat Big Endian: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11
quelle
byte[] bbb = ByteBuffer.allocate(4).putFloat(0.42f).array();
hat einbyte
Array erzeugt, das das Gegenteil von dem ist, was ichC/C++
produziert habe. Daher wirkt sich die große Endianness von Java auch in den Daten zur Laufzeit aus.