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
:
Verschoben durch User
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 | byte myByte = ...; |
2 | int unsingedByte = ((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
Die konvertierung in ein Long array ist unötig, du kannst auch einfach die bytes dirket casten so ist es etwas doppelt gemoppelt.
Danke für den Hinweis. Funktioniert nun alles wie gewollt.
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 |
12 | sb.append(strIncom); // String anhängen |
13 | int endOfLineIndex; |
14 | String path = "sdcard/" + dateipfad.getText().toString() + ".txt"; //Environment.getExternalStorageDirectory().getPath() |
15 | |
16 | while ((endOfLineIndex = sb.indexOf("|0|")) >= 0) { // wenn end-of-line, |
17 | String sbprint; // extrahiere String |
18 | sbprint = sb.substring(0, endOfLineIndex); |
19 | sb.delete(0, sb.length()); // und löschen |
20 | |
21 | try { |
22 | File myFile = new File(path); |
23 | myFile.createNewFile(); |
24 | FileOutputStream fOut = new FileOutputStream(myFile, true); |
25 | OutputStreamWriter myOutWriter = |
26 | new OutputStreamWriter(fOut); |
27 | myOutWriter.append(sbprint); |
28 | myOutWriter.close(); |
29 | fOut.close(); |
String strIncom = new String(ret, 0, msg.arg1); heißt es an dieser Stelle natürlich..
> 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
:
Bearbeitet durch User
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 :)
1 | for (int i = 0; i < readBuf.length - 2; i++) { |
2 | if (readBuf[i] == '|' && readBuf[i+1] == '0' && readBuf[i+2] == '|') { |
3 | endePos = i; |
4 | break
|
5 | }
|
6 | }
|
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..
Das müsste alles sein.
1 | Handler() { |
2 | public void handleMessage (android.os.Message msg){ |
3 | |
4 | |
5 | switch (msg.what) { |
6 | case RECIEVE_MESSAGE: |
7 | byte[] readBuf = (byte[]) msg.obj; |
8 | ByteArrayOutputStream baos = new ByteArrayOutputStream(readBuf.length); |
9 | |
10 | |
11 | |
12 | int[] ret = new int[readBuf.length]; |
13 | for (short i = 0; i < readBuf.length; i++) |
14 | { |
15 | ret[i] = (readBuf[i]&255); |
16 | } |
17 | |
18 | |
19 | String strIncom = new String(ret, 0, msg.arg1); // erstelle String aus Bytes Array |
20 | sb.append(strIncom); // String anhängen |
21 | int endOfLineIndex; |
22 | String path = "sdcard/" + dateipfad.getText().toString() + ".txt"; //Environment.getExternalStorageDirectory().getPath() |
23 | |
24 | while ((endOfLineIndex = sb.indexOf("|0|")) >= 0) { // wenn end-of-line, |
25 | String sbprint; // extrahiere String |
26 | sbprint = sb.substring(0, endOfLineIndex); |
27 | sb.delete(0, sb.length()); // und löschen |
28 | |
29 | try { |
30 | File myFile = new File(path); |
31 | myFile.createNewFile(); |
32 | FileOutputStream fOut = new FileOutputStream(myFile, true); |
33 | //OutputStreamWriter myOutWriter = |
34 | // new OutputStreamWriter(fOut); |
35 | //myOutWriter.append(sbprint); |
36 | //myOutWriter.close(); |
37 | fOut.write(readBuf); |
38 | fOut.close(); |
39 | |
40 | |
41 | |
42 | } catch (Exception e) { |
43 | Toast.makeText(getBaseContext(), e.getMessage(), |
44 | Toast.LENGTH_SHORT).show(); |
45 | } |
46 | } |
47 | break; |
48 | } |
49 | } |
50 | |
51 | } |
52 | |
53 | ; |
54 | |
55 | |
56 | private class ConnectedThread extends Thread { |
57 | private final InputStream mmInStream; |
58 | private final OutputStream mmOutStream; |
59 | |
60 | public ConnectedThread(BluetoothSocket socket) { |
61 | InputStream tmpIn = null; |
62 | OutputStream tmpOut = null; |
63 | |
64 | try { |
65 | tmpIn = socket.getInputStream(); |
66 | tmpOut = socket.getOutputStream(); |
67 | } catch (IOException e) { } |
68 | |
69 | mmInStream = tmpIn; |
70 | mmOutStream = tmpOut; |
71 | } |
72 | |
73 | public void run() { |
74 | byte[] buffer = new byte[1024]; // Pufferspeicher für den Stream |
75 | int bytes; // ausgegebene Bytes von read() |
76 | |
77 | |
78 | |
79 | // InputStream lesen bis Fehler auftreten |
80 | while (true) { |
81 | try { |
82 | // Lese InputStream |
83 | bytes = mmInStream.read(buffer); // Erhalte Anzahl der Bytes und der Daten in "buffer" |
84 | h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Sende zum Handler |
85 | } catch (IOException e) { |
86 | break; |
87 | } |
88 | } |
89 | } |
90 | |
91 | |
92 | public void write(String message) { |
93 | //Log.d(TAG, "...Data to send: " + message + "..."); |
94 | byte[] msgBuffer = message.getBytes(); |
95 | try { |
96 | mmOutStream.write(msgBuffer); |
97 | } catch (IOException e) { |
98 | |
99 | } |
100 | } |
101 | } |
102 | |
103 | |
104 | |
105 | |
106 | } |
Ich werde mich dann mal weiter einlesen, ich hoffe aber doch das mein Problem verständlich ist, oder?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.