2016-06-03 23 views
0

Ich bin mir wirklich nicht sicher, wie ich meine Frage formulieren soll, aber hier ist die Situation.Wie liest man ein Byte aus einer Textdatei als tatsächliches Byte in Hex anstelle von Zeichen?

Ich habe Daten in einer Textdatei, zum Beispiel: 0x7B 0x01 0x2C 0x00 0x00 0xEA diese Werte sind eine hexadezimale Darstellung von ASCII-Symbolen. Ich muss diese Daten lesen und in der Lage sein, entsprechend zu analysieren und zu übersetzen.

bisher Mein Problem ist, dass ive versucht, einen Scanner über so etwas wie scan.getNextByte mit() und wurde auf dem Posten gerichtet: [java.util.Scanner mit einer Feile Byte für Byte lesen]

Nach Ich ändere das Datei-Input-Format in einen File-Input-Stream und finde heraus, dass während ich sowas wie fis.read() mache, 48, den ASCII-Wert für das Zeichen 0 in 0x7B, zurückliege.

Ich bin auf der Suche nach einer Möglichkeit, die gelesenen Daten zu interpretieren, hat Hexadezimal, so 0x7B entspricht "{" in ASCII.

Hoffnung dies klar genug ist,

Danke,

+0

Sie müssen lese das ganze "Byte" ein - 0x7B anstatt nur 0 - in eine Zeichenkette und dann kannst du etwas wie 'Integer.decode (hexString)' – jonhopkins

+0

Warum hast du so eine Datei an erster Stelle? Nicht viel nutzen. – EJP

+0

Die Datei wird über die serielle Kommunikation generiert und meine Bewerbungsaufgabe ist basierend auf unseren Anforderungen zu interpretieren. Wir haben einen 64k-Block-Flash-Speicher, der in meinen Schoß geworfen wird, und ich muss in der Lage sein, den Header zu decodieren und darauf basierende Dateien zu generieren. – Tyler

Antwort

-1

Wenn Sie in der Lage, externe Bibliotheken zu verwenden, die Apache Commons Codec Bibliothek hat eine Hex Utility-Klasse, die eine Zeichen-Array-Darstellung drehen kann von hex in ein Byte-Array-Bytes:

final String hexChars = "0x48 0x45 0x4C 0x4C 0x4F"; 
// to get "48454C4C4F" 
final String plainHexChars = hexChars.replaceAll("(0x|)", ""); 
final byte[] hexBytes = Hex.decodeHex(plainHexChars.toCharArray()); 
final String decodedBytes = new String(hexBytes, Charset.forName("UTF-8")); 
+0

Würde es alles vereinfachen, wenn "0x" nicht vorhanden wäre? Ich glaube, dass ich die Daten manipulieren kann, bevor ich sie an diesem Punkt erhalte, so dass es nur Daten wie 7B 01 2C ... etc. – Tyler

+0

Ja, es würde die Dinge einfacher machen, wenn Sie die 0x und die Leerzeichen loswerden würden. Es macht es für Menschen etwas schwieriger zu lesen, aber der Konverter muss sich nicht mehr um die "Füllzeichen" kümmern, die keine Informationen enthalten. –

+0

In diesem Fall würde ich zwei Bytes auf einmal lesen, "7", dann "B" und verketten sie in eine Zeichenfolge, dann auf einen Hexadezimalwert? Verstehe ich richtig? – Tyler

1

Da Ihre Bytes durch Leerzeichen begrenzt sind, können Sie einfach einen Scanner verwenden, um sie zu lesen:

try (Scanner scanner = new Scanner(Paths.get(filename))) { 
    while (scanner.hasNext()) { 
     int byteValue = Integer.decode(scanner.next()); 
     // Process byteValue ... 
    } 
} 

Ich ermutige Sie, über die Integer.decode method und die Scanner class zu lesen.

+0

Das ist nah an dem, was ich ursprünglich gemacht habe und mir wurde gesagt, dass dies eine schreckliche Art ist, mit der Datei umzugehen, weil ich ein Byte (2 Zeichen) gleichzeitig lesen möchte. – Tyler

+1

@Tyler Ihre vorherige Frage war ein wenig unklar, und ehrlich gesagt, bin ich immer noch nicht klar: Enthält Ihre Datei eine * textuelle Darstellung jedes Bytes als vier ASCII-Zeichen, * oder schreiben Sie gerade 0x7B usw. in Ihre Frage um * us * zu zeigen, welche rohen Bytes in der eigentlichen Datendatei sind? – VGR

1

Wenn Sie skalierbare Lösung benötigen, versuchen Sie Ihre eigene Input

Grund Beispiel zu schreiben:

class ByteStringInputStream extends InputStream { 

    private final InputStream inputStream; 

    public ByteStringInputStream(InputStream inputStream) { 
     this.inputStream = inputStream; 
    } 

    private boolean isHexSymbol(char c) { 
     return (c >= '0' && c <= '9') 
       || (c >= 'A' && c <= 'F') 
       || (c == 'x'); 
    } 

    @Override 
    public int read() throws IOException { 

     try { 
      int readed; 
      char[] buffer = new char[4]; 
      int bufferIndex = 0; 

      while ((readed = inputStream.read()) != -1 && bufferIndex < 4) { 
       if (isHexSymbol((char) readed)) { 
        buffer[bufferIndex] = (char) readed; 
       } 
       bufferIndex++; 
      } 

      String stringBuffer = new String(buffer); 

      if (!stringBuffer.matches("^0x[0-9A-F]{2}$")) { 
       throw new NumberFormatException(stringBuffer); 
      } 

      return Integer.decode(stringBuffer); 

     } catch (Exception ex) { 
      inputStream.close(); 
      throw new IOException("<YOUR_EXCEPTION_TEXT_HERE>", ex); 
     } 
    } 

} 

Verbrauch:

ByteStringInputStream bsis = new ByteStringInputStream(new BufferedInputStream(System.in)); 
//you can use any InputStream instead 

while (true) { 
    System.out.println(bsis.read()); 
} 

Demo:

>0x7B 0x01 0x2C 0x00 0x00 0xEA 
123 
1 
44 
0 
0 
234