2015-04-24 4 views
5

У меня есть файл, который записывается в байтах, как этотПреобразовать байт в шестнадцатеричном до фактического байта

\r\x00\x00\x00\xd0{"a": "test"} 

, который имеет следующие байты

[13, 0, 0, 0, -48, 123, 34, 97, 34, 58, 32, 34, 116, 101, 115, 116, 34, 125] 

, когда этот файл считывается в Java Я получать все убежали

\\r\\x00\\x00\\x00\\xd0{"a": "test"} 

, когда я делаю .getBytes() на этой строке я получаю

[92, 114, 92, 120, 48, 48, 92, 120, 48, 48, 92, 120, 48, 48, 92, 120, 100, 48, 123, 34, 97, 34, 58, 32, 34, 116, 101, 115, 116, 34, 125] 

Мне нужно преобразовать строку в действительные байты, у меня нет возможности изменить способ чтения файла. Я знаю в Python, вы открываете файл с режимом 'rb', и вам хорошо идти. Если у java есть эта способность, я не могу ее использовать.

Итак, как можно преобразовать строку Java, читаемую в исходный массив байтов, который был записан в файл?

Извините, если этот вопрос глупый, но я настолько зеленый, когда речь идет о Java.

EDIT: Поэтому я считаю, что мой вопрос отличается от предложенной ссылки «дублированный вопрос». Он не принимает каждое буквальное значение в строке java и преобразует его обратно в байт. Считыватель читает строку в java. \x00 теперь \\x00, который не совпадает с байтом. Так что, наверное, мне нужен способ отмены строки?

файл, если смотреть в шестнадцатеричном редакторе

0000000: 5c72 5c78 3030 5c78 3030 5c78 3030 5c78 \r\x00\x00\x00\x 
0000010: 6430 7b22 6122 3a20 2274 6573 7422 7d0a d0{"a": "test"}. 

Строка, ява получает просмотрены в шестнадцатеричном редакторе

0000000: 5c5c 725c 5c78 3030 5c5c 7830 305c 5c78 \\r\\x00\\x00\\x 
0000010: 3030 5c5c 7864 307b 2261 223a 2022 7465 00\\xd0{"a": "te 
0000020: 7374 227d 0a        st"}. 
+5

Ну разъяснены и отформатированные вопросы никогда не глуп, по крайней мере для меня. – Maroun

+1

Как вы его читаете? – toadzky

+0

Результаты, полученные у getBytes(), это то, что вы ожидаете? – Shar1er80

ответ

1

В Java вам нужно будет интерпретировать входную строку, чтобы получить значения байтов, которые вы хотите.

Я написал приложение Java, которое интерпретирует входную строку.

Вот строка ввода:

\r\x00\x00\x00\xd0{"a": "test"} 

Вот результат:

[13, 0, 0, 0, -48, 34, 97, 34, 58, 32, 34, 116, 101, 115, 116, 34, 125] 

А вот код. Вероятно, вам придется немного изменить код, чтобы обрабатывать случаи, которые вы не задали в своем вопросе.

package com.ggl.testing; 

import java.io.BufferedReader; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

public class ConvertBytes implements Runnable { 

    private String fileName; 

    public static void main(String[] args) { 
     new ConvertBytes("bytes.txt").run(); 
    } 

    public ConvertBytes(String fileName) { 
     this.fileName = fileName; 
    } 

    @Override 
    public void run() { 
     BufferedReader br = null; 

     try { 
      br = new BufferedReader(new InputStreamReader(getClass() 
        .getResourceAsStream(fileName))); 
      String line = ""; 
      while ((line = br.readLine()) != null) { 
       processLine(line); 
      } 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       if (br != null) { 
        br.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    private void processLine(String line) { 
     String[] parts = line.split("(?=\\\\)"); 
     List<Byte> byteList = new ArrayList<Byte>(); 

     for (int i = 0; i < parts.length; i++) { 
      if (parts[i].equals("")) { 
       continue; 
      } else { 
       byteList.addAll(getValue(parts[i])); 
      } 
     } 

     Byte[] bytes = byteList.toArray(new Byte[byteList.size()]); 
     System.out.println(Arrays.toString(bytes)); 
    } 

    private List<Byte> getValue(String s) { 
     List<Byte> byteList = new ArrayList<Byte>(); 

     if (s.startsWith("\\x")) { 
      int value = Integer.valueOf(s.substring(2, 4), 16); 
      if (value > 127) { 
       value = value - 256; 
      } 
      byteList.add(Byte.valueOf((byte) value)); 
      if (s.length() > 4) { 
       byteList.addAll(getAsciiValue(s.substring(5))); 
      } 
     } else if (s.equals("\\r")) { 
      byteList.add(Byte.valueOf((byte) 13)); 
     } else if (s.equals("\\t")) { 
      byteList.add(Byte.valueOf((byte) 9)); 
     } else { 
      byteList.addAll(getAsciiValue(s)); 
     } 

     return byteList; 
    } 

    private List<Byte> getAsciiValue(String s) { 
     List<Byte> byteList = new ArrayList<Byte>(); 

     for (int i = 0; i < s.length(); i++) { 
      int value = (int) s.charAt(i); 
      byteList.add(Byte.valueOf((byte) value)); 
     } 

     return byteList; 
    } 

} 

Файл bytes.txt должен быть в том же каталоге, что и приложение Java.

0

Вы не получаете «все убежали», когда файл читается в Java. Почему вы так думаете? Преобразование в байты показывает, что String содержит именно то, что показывает шестнадцатеричный редактор в файле. Другими словами,

92, 114, 92, 120, 48, 48, 92, 120, 48, 48, 92, 120, 48, 48, 92, 120 (десятичное)

такая же, как

5c72 5c78 3030 5c78 3030 5c78 3030 5c78 (шест)

Если вы хотите, чтобы декодировать управляющие последовательности , которые находятся в файле , вам нужно будет написать код для их обработки; это не проблема кодирования символов.

1

Похоже, что вам нужно самостоятельно разобрать линию "String".

Я бы карту беглых символов ('\ г', '\ п', '\ Ь', и т.д. ...)

private static Map<String, Byte> escapedCharacters; 
static { 
    escapedCharacters = new HashMap<>(); 
    escapedCharacters.put("\\b", (byte)'\b'); 
    escapedCharacters.put("\\f", (byte)'\f'); 
    escapedCharacters.put("\\n", (byte)'\n'); 
    escapedCharacters.put("\\r", (byte)'\r'); 
    escapedCharacters.put("\\t", (byte)'\t'); 
    // Add more if needed 
}; 

Тогда следующий обработать файл:

public static void main(String[] args) throws Exception { 
    String myFile = "PathToYourFile"; 

    // Read your file in 
    List<String> myFileLines = Files.readAllLines(Paths.get(myFile)); 

    // List to hold all the lines as translated bytes 
    List<byte[]> myFileLinesAsBytes = new ArrayList<>(); 
    for (String line : myFileLines) { 
     myFileLinesAsBytes.add(translateEscapedBytes(line)); 
    } 

    // Displays all translated lines 
    for (byte[] byteLine : myFileLinesAsBytes) { 
     System.out.println(Arrays.toString(byteLine)); 
    } 
    System.out.println(); 
} 

private static byte[] translateEscapedBytes(String line) throws UnsupportedEncodingException { 
    List<Byte> translatedBytes = new ArrayList<>(); 
    for (int i = 0; i < line.length();) { 
     if (line.charAt(i) == '\\') { // Escaped byte 
      String escapedByte = line.substring(i, i + 2); 
      if (escapedByte.endsWith("x")) { // Hexidecimal number 
       escapedByte = line.substring(i + 2, i + 4); // + 4 to get the two numbers after \x 
       translatedBytes.add(hexStringToByte(escapedByte)); 
       i += 4; 
      } else { // Escaped character 
       translatedBytes.add(escapedCharacters.get(escapedByte)); 
       i += 2; 
      } 
     } else { // Non Escapted Character 
      translatedBytes.add((byte)(line.charAt(i))); 
      i++; 
     } 
    } 

    // Copy List to actual byte[] to return 
    byte[] result = new byte[translatedBytes.size()]; 
    for (int i = 0; i < translatedBytes.size(); i++) { 
     result[i] = translatedBytes.get(i); 
    } 
    return result; 
} 

private static byte hexStringToByte(String s) { 
    return (byte) ((Character.digit(s.charAt(0), 16) << 4) + Character.digit(s.charAt(1), 16)); 
} 

translatedEscapedBytes() ищет символ «\» в строке и определяет, что в сочетании со следующим символом у вас будет экранированный символ. Если escape-символ - это \ x, то вы знаете, что следующие два числа - это шестнадцатеричное число, которое необходимо преобразовать в байт (hexStringToByte(String s)), иначе скрытый escape-символ в байт, используя карту экранированных символов. Все остальные символы рассматриваются как неэкранированные символы и просто преобразуются в их байтовое значение.

Результаты (с использованием данных, которые были указаны):

enter image description here