Datentypen int in bytes zerlegen und wieder zusammen setzen

chaostheory

Bekanntes Mitglied
Hallo,
ich will über einen DataOutputStream Integer-Werte versenden, möchte diese aber in bytes zerlegen und beim Empfänger wieder zusammen setzen.
Nun habe ich einige Methoden im Internet gefunden und gemerkt, dass ich noch einiges über Bitverschiebungen lernen muss.
Eine Methode war folgende:
Java:
public static final int byteArrayToInt(byte [] b) {
        return (b[0] << 24)
                + ((b[1] & 0xFF) << 16)
                + ((b[2] & 0xFF) << 8)
                + (b[3] & 0xFF);
}
Dass & eine Und-Verknüpfung ist, weiß ich bereits. Aber ich dachte das geht nur bei Bits, wie werden ganze Bytes überprüft? Und wofür ist das nötig?
Und warum schreibt man 255 hexadezimal?
Noch eine Frage: Verschiebt man Bits um 16 Stellen, wie oben geschehen, sprengt das doch den 8-bit Rahmen eines bytes. Werden die Werte dann als Integer gespeichert?

Vielen Dank!
 

Marco13

Top Contributor
Ein byte besteht aus bits ... :bahnhof:

Die 0xFF schreibt man oft, weil bei der Hex-Schreibweise das "Muster" erhalten bleibt. Bei sowas wie
int a = b & 0x00FF00FF;
sieht man sofort: Ah, das 0. und 2. byte bleiben erhalten. Bei
int a = b & 16711935;
sieht man das nicht so direkt ;)

Wenn man bytes verschiebt, werden sie in int konvertiert und als solche "gespeichert" (bzw. es wird als ints mit ihnen weitergrechnet).
 

AquaBall

Top Contributor
Die Funktion geht von 4 Byte aus, also wie du richtig bemerkst eigentlich long int. Ist wohl nur ein Übungsbeispiel.

Ob man 255 oder 0xff schreibt ist an allen Stellen in Java egal, zeigt hier aber besser die Absicht.

Das & ist kein logisches und, sonder ein binäres und.
Mit & 0xff werden alle anderen Bits auf 0 gesetzt.

0011010110100100110101100011 &
0000000000000000111111110000 ergibt
0000000000000000110101100000

Alles klar?
 

chaostheory

Bekanntes Mitglied
Dass Bytes aus Bits bestehen war mit schon klar :)
Aber was passiert wenn man nun ein Byte mit 0x00FF00FF vergleicht? Werden alle Bits einzeln verglichen und neu gesetzt?
Also wäre [0100 0100] &
[0010 0111]
=[0000 0100]
?
 

chaostheory

Bekanntes Mitglied
Die Funktion geht von 4 Byte aus, also wie du richtig bemerkst eigentlich long int. Ist wohl nur ein Übungsbeispiel.

Ob man 255 oder 0xff schreibt ist an allen Stellen in Java egal, zeigt hier aber besser die Absicht.

Das & ist kein logisches und, sonder ein binäres und.
Mit & 0xff werden alle anderen Bits auf 0 gesetzt.

0011010110100100110101100011 &
0000000000000000111111110000 ergibt
0000000000000000110101100000

Alles klar?

Aha, ok. Und warum muss man bei der Konvertierung zu einem Integer die Bytes erst mit 0xff verknüpfen?
 
S

Spacerat

Gast
Mit dem 0xFF werden negative Integerwerte isoliert. Das ist nötig, damit ein Streamende-Signal (int -1) erkannt werden kann welches nicht mehr als Byte gewertet werden darf.
BTW.: Binäre und logische Verknüpfungen sind gegenseitig synonym. Das alleinstehende "&" ist eine bitweise logische Verknüpfung von Integerwerten >= 1 Bit.
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
So nebenbei: Es wäre sinnvoller, die einzelnen Teil-Terme hier nicht mit "+" zu verbinden, sondern mit "|". Damit ist klarer, was gemacht wird, und es kann auch effizienter sein.


Und noch was ganz anderes: Wenn du viele bytes in einem Array hast, kannst du dir das krampfige Zeux mit den Bitoperationen und sogar ein Eventeuelles Kopieren von jeweils 4 bytes in einen Array, um ihn an diese Methode zu übergeben, sparen: Wenn man den byte-Array in einen ByteBuffer einwickelt, den man dann als IntBuffer ansieht, kann man direkt als ints auf die Daten zugreifen - lesend und schreibend.

Java:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;


public class ByteIntConversion
{
    public static void main(String[] args)
    {
        byte data[] = new byte[]{
            (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78, 
            (byte)0x9A, (byte)0xBC, (byte)0xDE, (byte)0xFF, 
        };
  
        IntBuffer ib = ByteBuffer.wrap(data).order(
            ByteOrder.nativeOrder()).asIntBuffer();
        
        int i0 = ib.get(0);
        int i1 = ib.get(1);

        System.out.println("Read ints:");
        System.out.println(Integer.toHexString(i0));
        System.out.println(Integer.toHexString(i1));
        
        ib.put(0, 0x11223344);
        ib.put(1, 0x55667788);

        System.out.println("Wrote ints, bytes now:");
        for (int i=0; i<data.length; i++)
        {
            System.out.println(Integer.toHexString(data[i]&0xFF));
        }
    }
}
 

Marco13

Top Contributor
Da du den Grund dafür bisher nicht verraten hast, sollte es mal nicht unerwähnt bleiben, dass es diese Möglichkeit auch noch gibt ;)
 

chaostheory

Bekanntes Mitglied
Ich habe es gerade eben doch in sendInt() geändert :) Da ich eigentlich nur Integer-Werte versende, war das ziemlich unsinnig.
Meine Idee war, so viel wie möglich selbst zu schreiben und nicht alles einer fertigen API zu überlassen. Aber die eine Konvertierung macht da auch keinen großen Unterschied mehr und die Variante ist wohl doch sehr viel effizienter.
Aber das Problem interessiert mich immer noch :D
 

irgendjemand

Top Contributor
hmm ... rad neu erfinden ... immer wieder ne wunderschöne sache ... obwohl eigentlich jedem in der softwareentwicklung eingetrichtert wird das das eben NICHT machen sondern vorhandene APIs nutzen soll ...

da ich weis worauf sich dieser thread hier bezieht : wenn du schon mit DataInput/OutputStream arbeitest ... warum willst du dir dann noch die mühe machen und selbst int <-> byte konvertieren wenn das bereits durch Data*Stream erledigt wird ?
 
S

Spacerat

Gast
Das Thema ist zwar inzwischen Erledigt, aber trotzdem. Die DataInput- bzw. OutputStream kann man vergessen, sobald man BigEndian schreiben oder lesen will. Einen Ansatz dazu hat Marco bereits gepostet. Im übrigen, @Marco: Die Wandlung in einen IntBuffer ist überflüssig. ByteBuffer hat ähnliche Methoden wie DataInput bzw. -Output ([c]getInt()[/c] usw). Dieses Rad kann man durchaus neu erfinden.
Und wenn man das Rad nur zu übungszwecken neu erfindet, ist das auch kein Problem.
 
S

Spacerat

Gast
Sorry für den Doppelpost, aber bei meinem letzten, gab es eine fatale Verwechslung (kein Wunder, nach meiner Logik sollte bei BigEndian Big auch am Ende stehen, aber neee... XD). Die DataStreams lesen bzw. schreiben BigEndian. Aber nicht nur diese Verwechslung ist fatal, sondern auch der Umstand, dass sehr viele vor allem neue Dateiformate LittleEndian verwenden.
@mich und all jene die es sich nicht merken können: Merkt's euch endlich. Bei LittleEndian stehen die kleinen Werte am Anfang, auch wenn dort "kleines Ende" steht! Bei BigEndian stehen die hohen Werte am Anfang, auch wenn dort "grosses Ende" steht! :lol:
 

Marco13

Top Contributor
@Marco: Die Wandlung in einen IntBuffer ist überflüssig. ByteBuffer hat ähnliche Methoden wie DataInput bzw. -Output ([c]getInt()[/c] usw). Dieses Rad kann man durchaus neu erfinden.

Hmja... da muss man ggf. aufpassen, dass man sich nicht einen int holt, der eine gräßliche Mutation aus zwei anderen ints ist :autsch:, weil man einen falschen Offset/Index verwendet hat ... ;)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C BufferedReader/BufferedWriter schreibt nicht alle Bytes Allgemeine Java-Themen 2
V Input/Output Austausch von Bytes zwischen C# und Java Allgemeine Java-Themen 3
RalleYTN Input/Output Clip als ein Array von Bytes? Allgemeine Java-Themen 2
J Temperatur aus bytes auslesen. Allgemeine Java-Themen 13
Q Bytes verschwinden im CipherInputStream Allgemeine Java-Themen 1
L Methoden Methode gibt mir beim verschlüsseln mit RSA 0 bytes aus ? Allgemeine Java-Themen 1
J Bytes aus Socket lesen Allgemeine Java-Themen 9
Q Datentypen Short aus Bytes - Signed -> Unsigned? Allgemeine Java-Themen 9
K Hexadezimale Bytes Allgemeine Java-Themen 6
B bereits gelesene Bytes herausfinden Allgemeine Java-Themen 10
M FIFO Queue: bytes in, float/double/etc out Allgemeine Java-Themen 5
S String zu binary und zurück - Problem mit unsigned/signed bytes Allgemeine Java-Themen 2
TiME-SPLiNTER Von Unix, InputStreams und Null Bytes Allgemeine Java-Themen 2
K AES, Buffer und Bytes Allgemeine Java-Themen 2
S Bytes oder Hex-Werte zu Assembler Code? Allgemeine Java-Themen 6
L bytes nach int (little endian bitshift) Allgemeine Java-Themen 12
J Receive eines Hex-Bytes über COM-Port Allgemeine Java-Themen 4
G Zwei bytes vergleichen Allgemeine Java-Themen 2
M Bytes in Datei schreiben Allgemeine Java-Themen 10
T Spezielle Bytes in Datei schreiben Allgemeine Java-Themen 7
F Einlesen von Bytes Allgemeine Java-Themen 9
reibi Größe Array aus bytes Allgemeine Java-Themen 14
G RXTX verschicken einzelener Bytes Allgemeine Java-Themen 8
G WAV-Samples bearbeiten oder: 2 Bytes -> short -> float Allgemeine Java-Themen 5
T Größe eine Variablen in Bytes? Allgemeine Java-Themen 22
G Mehrere Bytes auf einmal einlesen Allgemeine Java-Themen 4
P int -> 4 bytes Allgemeine Java-Themen 11
R Menge an Bytes eines OutputStreams ermitteln. Allgemeine Java-Themen 6
R Wieviele Bytes gesendet Allgemeine Java-Themen 3
T Bestimmte bytes in einer Datei ersetzen? Allgemeine Java-Themen 4
D 16-Bit int --> 2* 8-Bit Bytes Allgemeine Java-Themen 17
H Objekte verbrauchen immer mindestens 16 Bytes Allgemeine Java-Themen 3
W Array größer als 65536 Bytes Allgemeine Java-Themen 7
A RandomAccessFile - Bytes vom Anfang der Datei löschen Allgemeine Java-Themen 32
C Code of a method longer than 65535 bytes Allgemeine Java-Themen 3
L 8 bytes von bestimmter position weg lesen? Allgemeine Java-Themen 11
D 2 Bytes in ein int convertieren Allgemeine Java-Themen 2
B Umwandeln von Bytes in float Zahl (DataInputStream) Allgemeine Java-Themen 3
G 0 Bytes bei temporäre Datei. Warum? Allgemeine Java-Themen 6
Ü Eurobeträge in möglichst wenig Scheine/Münzen zerlegen (2D-Arrays) Allgemeine Java-Themen 27
J Zerlegen einer Zahl Allgemeine Java-Themen 6
Neumi5694 Parser - Zerlegen verschachtelter Funktionen Allgemeine Java-Themen 2
A ALTER TABLE mit Hilfe von RegEx zerlegen, splitten Allgemeine Java-Themen 5
F String in feste Größe zerlegen Allgemeine Java-Themen 11
H String zerlegen Allgemeine Java-Themen 2
S Threads Liste mit Objekten in Teillisten zerlegen und abarbeiten Allgemeine Java-Themen 3
J String zerlegen in einzelne Strings Allgemeine Java-Themen 7
D String zerlegen Allgemeine Java-Themen 12
R JAI - RGB Bild in 3 Einzelbilder zerlegen Allgemeine Java-Themen 4
X String zerlegen mittels regulärem Ausdruck Allgemeine Java-Themen 31
N String in einzelne Zeichen zerlegen Allgemeine Java-Themen 8
K List in Teillisten zerlegen Allgemeine Java-Themen 2
H Log zerlegen Allgemeine Java-Themen 23
G Strings zerlegen und substrings auslesen Allgemeine Java-Themen 2
K String zerlegen wie? Allgemeine Java-Themen 8
A Wort in seine Buchstaben zerlegen Allgemeine Java-Themen 37
M Link parsen bzw. zerlegen Allgemeine Java-Themen 9
S String analysieren, zerlegen und überarbeiten Allgemeine Java-Themen 4
T Objekte eindeutig zerlegen und wieder zusammen bauen? Allgemeine Java-Themen 6
Luma String in seine Buchstaben zerlegen? Allgemeine Java-Themen 3
B Datenstruktur elegant zerlegen Allgemeine Java-Themen 6
B Strings zerlegen Allgemeine Java-Themen 9
M String zerlegen? Allgemeine Java-Themen 2
Oneixee5 Oracle, wieder mal ... Allgemeine Java-Themen 12
E Objekte in einen String packen und wieder laden Allgemeine Java-Themen 5
LimDul Kam eine java.net.URL zu einer HashMap und ging als DNS Anfrage wieder heraus Allgemeine Java-Themen 18
W Vererbung Generics - mal wieder die verhaßte Rückwärtskompatibilität Allgemeine Java-Themen 2
V Scheinbar zufällig hin und wieder: Can't create an ImageOutputStream! Allgemeine Java-Themen 8
J Variablen Mehrere int-variablen in txt abspeichern und danach wieder auslesen Allgemeine Java-Themen 1
X NetBeans Bilder und andere Dateien ins .jar schreiben und wieder aus .jar lesen Allgemeine Java-Themen 6
2 String Array in Datei schreiben und wieder davon lesen Allgemeine Java-Themen 2
F JLabel nach 5 Sekunden wieder leeren Allgemeine Java-Themen 7
Thallius Dateien Zippen und wieder heraus lesen? Allgemeine Java-Themen 4
S Zahlen aus (String mit zahlen) immer wieder neu auslesen Allgemeine Java-Themen 5
OnDemand Input/Output Variablen in Datei Speichern um sie wieder auszulesen Allgemeine Java-Themen 4
iB0T "goto" Befehl aus Batch in Java und Variablen wert immer wieder neu setzen Allgemeine Java-Themen 4
M Regex... mal wieder Allgemeine Java-Themen 3
M CapsLock abfragen wenn Fenster wieder aktiviert wird Allgemeine Java-Themen 5
B Mal wieder "Could not find the main class" Allgemeine Java-Themen 3
S Strings gehen "kaputt" wenn ich in CVS ein und wieder auschecke. Allgemeine Java-Themen 2
F Wieder mal die eBay API Allgemeine Java-Themen 3
E Speicherverwaltung bzw. Speicher wieder frei geben?! Allgemeine Java-Themen 8
T JConsole: Klassen werden geladen aber nicht wieder entladen Allgemeine Java-Themen 3
S Thread vorübergehend stilllegen und wieder aufwecken Allgemeine Java-Themen 18
data89 A-Stern: fährt immer wieder vor die Wand! - Hilfeeee Allgemeine Java-Themen 7
L Thread kurz unterbrechen und wieder starten Allgemeine Java-Themen 5
L Applet immer wieder neu laden - Problem Allgemeine Java-Themen 25
T RegEx, wieder einmal ... :-( Allgemeine Java-Themen 19
S Wieso stehen in der API immer wieder abstrakte Methoden ? Allgemeine Java-Themen 7
C Aus XML ein DOM Objekt und wieder zurück Allgemeine Java-Themen 2
M wieder mal applet probleme Allgemeine Java-Themen 17
A HTML-Seite wieder schließen Allgemeine Java-Themen 2
W Wieder einmal: PNG ausdrucken Allgemeine Java-Themen 3
S GUI komplett schließen und wieder Neu laden? Allgemeine Java-Themen 4
C Bild in .txt speichern und wieder als Bild speichern Allgemeine Java-Themen 2
Y Mal wieder vergleichen von Strings.[Leider noch ein Problem] Allgemeine Java-Themen 18
A String in umgekehrter reihenfolgen wieder geben Allgemeine Java-Themen 16
GilbertGrape mal wieder ne Regex-Frage Allgemeine Java-Themen 2
A Javakonsolenfenster geht gleich wieder zu Allgemeine Java-Themen 6
G Schon wieder Regex Problem :-/ Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben