2012-10-11 8 views
5

Ich schreibe einen Code, um einen Strom von Binärdaten zu verarbeiten. Es wird in Blöcken empfangen, die durch Byte-Arrays dargestellt werden. Kombiniert stellen die Bytearrays einen sequentiellen Nachrichtenstrom dar, von denen jeder mit dem gleichen konstanten Terminatorwert endet (in meinem Fall 0xff). Der Terminatorwert kann jedoch an einem beliebigen Punkt in einem bestimmten Datenblock auftreten. Ein einzelner Chunk kann einen Teil einer Nachricht, mehrere Nachrichten und alles dazwischen enthalten.Tokenisieren von Binärdaten in Java

Hier ist eine kleine Auswahl dessen, was durch diese verarbeiteten Daten aussehen könnte:

[0x00, 0x0a, 0xff] 
[0x01, 0x01, 0x01, 0xff] 
[0x01, 0xff] 

Ich habe eine kleine Klasse geschrieben zu handhaben:

[0x00, 0x0a, 0xff, 0x01] 
[0x01, 0x01] 
[0xff, 0x01, 0xff] 

sollten diese Daten in diese Nachrichten konvertiert werden Dies. Es hat eine Methode, um einige Daten im Byte-Array-Format hinzuzufügen, die dann in einem Puffer-Array platziert werden. Wenn das Terminatorzeichen gefunden wird, wird das Bytearray gelöscht und die vollständige Nachricht wird in eine Nachrichtenwarteschlange gestellt, auf die mit den Methoden hasNext() und next() (ähnlich einem Iterator) zugegriffen werden kann.

Diese Lösung funktioniert gut, aber als ich fertig war, wurde mir klar, dass es vielleicht bereits einen stabilen, performanten und getesteten Code in einer etablierten Bibliothek gibt, die ich stattdessen verwenden könnte.

Also meine Frage ist - kennen Sie eine Dienstprogramm-Bibliothek, die eine solche Klasse hätte, oder vielleicht gibt es etwas in der Standard-Java-6-Bibliothek, die das schon tun kann?

+0

Byte-Array suchen und Manipulation ist etwas, was ich manchmal in Java verpassen. Man kann eine gepufferte Byte-Stream-Kindklasse verwenden, die einen Test pro Byte für "0xff" durchführen kann. In einigen Fällen kann man eine Pipeline verwenden: siehe [PipedInputStream] (http://docs.oracle.com/javase/6/docs/api/java/io/PipedInputStream.html) usw. –

Antwort

1

Ich glaube nicht, dass Sie ein Framework benötigen, da ein benutzerdefinierter Parser einfach genug ist.

InputStream in = new ByteArrayInputStream(new byte[]{ 
     0x00, 0x0a, (byte) 0xff, 
     0x01, 0x01, 0x01, (byte) 0xff, 
     0x01, (byte) 0xff}); 

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
for (int b; (b = in.read()) >= 0;) { 
    baos.write(b); 
    if (b == 0xff) { 
     byte[] bytes = baos.toByteArray(); 
     System.out.println(Arrays.toString(bytes)); 
     baos = new ByteArrayOutputStream(); 
    } 
} 

Drucke als (byte) 0xFF == -1

[0, 10, -1] 
[1, 1, 1, -1] 
[1, -1] 
+0

Danke für die Antwort. Es sieht vielversprechend und sicherlich eleganter aus als das, was ich habe, aber die Daten, die ich habe, kommen als separate Byte-Arrays, nicht als ein Byte-Array wie in dem Beispiel, das Sie angegeben haben. – Sevas

+0

Woher kommt es als 'byte []'? Liest du von einem Gerät oder Netzwerk? –

+0

Es wird tatsächlich von einer seriellen Schnittstelle gelesen, so dass die Daten wie eine Reihe von Byte-Arrays aussehen – Sevas