Hallo,
ich stehe gerade vor einem kleinen "Problemchen".
Ich möchte in Java einen einkommenden Bytestream sortieren und dann in
einen Integer wandeln. Jetzt gibt es ja die bereitgestellten
Inputstreamfunktionen die mir die ankommenden Bytes in einen Bytearray
speichert.
Jetzt ist es so das ein ankommendes Byte mit dem Wert 0x80 oder höher
als signed gespeichert wird. Also -128 im Falle von 0x80 da ja das
Vorzeichenbit gesetzt ist.
Weiss jemand wie ich das am besten handeln kann, sodass ein empfangenes
0x80 auch wirklich als +128 gespeichert wird. Mit Typcast? Bloß wie und
in was?
Gruß
Jonny
Jonny schrieb:> mit dem Wert 0x80 oder höher> als signed gespeichert wird
Bytes sind immer signed, generelll ist jeder Integer-Datentyp in Java
signed.
Was genau möchtest du den dort sortieren?
Am einfachstem wäre es wohl wenn du das ganze in int konvertierst etwa
so:
1
bytemyByte=...;
2
intunsingedByte=((int)myByte)&0xFF;
Alternativ kannst du ja auch die bytes einzeln über die read Funktion
gleich als int lesen.
Danke für die Antwort. Ich sortiere die Bytes sodass das MSB vorne
steht. Ich verwende nun eine Konvertierung, allerdings zu long, da int
nicht ausreichend ist.
Dazu verwende ich die Funktion:
long ByteArrayToLong(byte[] b)
{
long[] buf = {(((long)b[0]) & 0xFF),(((long)b[1]) &
0xFF),(((long)b[2]) & 0xFF),(((long)b[3]) & 0xFF)};
return buf[3] & 0xFF |
(buf[2] & 0xFF) << 8 |
(buf[1] & 0xFF) << 16 |
(buf[0] & 0xFF) << 24;
}
Nun funktioniert alles. Danke nochmal.
Gruß
Jonny
Hallo auch wenn der Thread etwas älter ist, selbes Problem wie der TE,
ich mache mal kein neuen auf...
Läubi .. schrieb:> Bytes sind immer signed, generelll ist jeder Integer-Datentyp in Java> signed.
Ich hab versucht jedes Element in meinem Input-stream mit 0&FF zu
erweitern... die untere Hälfte des Wertebereichs ist alles richtig, aber
statt einer 0x80 erhalte ich dann eine: c2 80,
für 0x81 eine c2 81, für 0x82 c2 82, usw....
statt eine FF erhalte ich: c3 bf; was das für ein Quatsch?
Bitte um Hilfe. Bin Java-Laie, danke :)
1
byte[] readBuf = (byte[]) msg.obj;
2
3
4
int[] ret = new int[readBuf.length];
5
for (short i = 0; i < readBuf.length; i++)
6
{
7
ret[i] = (readBuf[i]&255);
8
}
9
10
11
String strIncom = new String(readBuf, 0, msg.arg1); // erstelle String aus Bytes Array
> String strIncom = new String(readBuf, 0, msg.arg1);
Hier verwendest du 1. den Originalbuffer und 2 passiert hier sehr
wahrscheinlich eine Zeichensatzkodierung.
/edit sehe gerade deinen Korrekturpost, deshalb streich 1.
Wenn du ein Byte-Array 1:1 weg schreiben willst, darfst du es nicht auf
String konvertieren (da java die Bytes dann nach UTF-8 konvertiert)
Verwende einen ByteArrayOutputStream (eine Konvertierung nach Int ist
dann nichz notwendig) und suche nach der Ende-Markierung zu fuß
Gruß Roland
Hallo Roland und vielen Dank.
Roland P. schrieb:> passiert hier sehr> wahrscheinlich eine Zeichensatzkodierung.
das ist wohl mein Problem, genau.
Roland P. schrieb:> Wenn du ein Byte-Array 1:1 weg schreiben willst
das will ich, einfach eine Art "Terminal"
Roland P. schrieb:> darfst du es nicht auf> String konvertieren (da java die Bytes dann nach UTF-8 konvertiert)
das habe ich gemerkt. :(
Roland P. schrieb:> Verwende einen ByteArrayOutputStream (eine Konvertierung nach Int ist> dann nichz notwendig)
ok.
>und suche nach der Ende-Markierung zu fuß
Wie sieht sowas denn dann aus?
Ich hatte mal folgendes probiert:
1
byte[] readBuf = (byte[]) msg.obj;
2
3
try {
4
File myFile = new File(path);
5
myFile.createNewFile();
6
FileOutputStream fOut = new FileOutputStream(myFile, true);
7
8
fOut.write(readBuf);
9
fOut.close();
...Wunderbar, meine 0xFF sind da. Natürlich fehlt jetzt der Index und
der Buffer wird willkürlich ausgelesen.
Kannst du mir vlt. helfen wie ich da ohne Stringkonvertierung einen
Index einführe?
Kann ich nicht statt |0|
verwenden:
0x7c 0x00 0x7c o.ä.? ??
Danke im Voraus. Gruß zurück :)
Roland P. schrieb:> for (int i = 0; i < readBuf.length - 2; i++) {> if (readBuf[i] == '|' && readBuf[i+1] == '0' && readBuf[i+2] == '|') {> endePos = i;> break> }> }
Danke für deine schnelle Antwort Roland und sorry, dass ich dir nicht
auf Anhieb folgen kann. (Java = sehr unerfahren).
durch int endePos = i, habe ich dann die Stelle an der der Index steht?
Aber wie verwende ich die nun richtig ôÔ ?
Aus deinem Code versteht ich nicht was du wirklich willst. Daher hier
nur Grundsätzliches:
...Reader / ...Writer sind für Text.
...InputStream / ...OutputStream sind für Daten.
Es zählt immer das Ende des Klassennamens. Beispiel: Ein
InputStreamReader ist ein Reader (also für Text), der in diesem Fall
seine Rohdaten aus einem InputStream bekommen kann.
Das Mischen von Reader und InputStream, bzw. Writer und OutputStream
sollte nur kontrolliert erfolgen und dann sollte man wissen was man tut.
Zum kontrollierten Mischen gehört, dass man ein Encoding angibt oder
sich drei mal vergewissert hat, dass der Default das gewünschte Encoding
ist.
Daten die ein Gemisch aus Text und Binärdaten sind kann man mit
DataInputStream lesen wenn man sie mit DataOutputStream geschrieben hat.
Für beliebige Dateiformate sind die beiden Klassen zu unflexibel.
Ähnlich eingeschränkt sind diverse andere Klassen die DataInput bzw.
DataOutput implementieren.
Für kompliziertere Operationen auf beliebige Dateiformate,
einschließlich der Änderung der Endianess, kann man auf "new" IO
(java.nio) Klassen wechseln. Insbesondere ByteBuffer. Um ein ByteBuffer
zu bekommen beginnt man mit einer wrap() oder allocate() Methode oder
liest von einem FileChannel.
Ein "|o|" als Ende-Markierung in eine Binärdatei zu schreiben ist
reichlich merkwürdig. Wer gibt einem die Garantie, dass normale Daten
nicht zufällig "|o|" enthalten? Entweder weiß man von vornherein wie
lang die Daten sind, oder man schreibt zuerst die Länge der Daten, dann
die Daten. Bei Text kann man auch Null-Terminierte Daten schreiben, wenn
das Encoding garantiert, dass \0 nie innerhalb des encodierten Textes
auftritt.
Hi Jack und danke für deine ausführliche Antwort.
Jack schrieb:> ...InputStream / ...OutputStream sind für Daten.
ok, ich bin noch sehr neu in diesem Gebiet.. da es zum größtenteil
funktioniert hat, dachte ich es schnell fertig zu bekommen... :(
Jack schrieb:> Ein "|o|" als Ende-Markierung in eine Binärdatei zu schreiben ist> reichlich merkwürdig. Wer gibt einem die Garantie, dass normale Daten> nicht zufällig "|o|"
gibt keine Garantie, aber selbst wenn, dann wird doch der Index nur
einmal verrückt beim ersten Code und ein kürzerer String extrahiert?
Dadurch geht doch nichts verloren? Oder liege ich da falsch.
Jack schrieb:> Entweder weiß man von vornherein wie
soll ja ein Stream werden, µC schickt permanent Werte.
Ich kenne die Anzahl der Bytes pro mein definiertes Paket..
Der erste Code war schon so wie ich ihn haben wollte.. eigentlich..