Как прочитать шестнадцатеричные значения из файла в байтовый массив? - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть файл, который состоит из комментариев (выглядят как однострочные комментарии Java, начинающиеся с двойной косой черты, //) и шестнадцатеричных значений, разделенных пробелами.

Файл выглядит следующим образом:

//create applet instance
0x80 0xB8 0x00 0x00 0x0c 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x00 0x7F;

Как преобразовать строку, в которой шестнадцатеричные значения идут от строки к байтовому массиву?

Я использую следующий подход:

List<byte[]> commands = new ArrayList<>();
Scanner fileReader = new Scanner(new FileReader(file));
while (fileReader.hasNextLine()) {
      String line = fileReader.nextLine();
      if (line.startsWith("0x")) {
          commands.add(line.getBytes());
      }
}

Но, безусловно, это показывает представление байтовсимволов, поскольку они были символами и не преобразовывают это в байт.Вот так.Но как его правильно конвертировать?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Просто подумал, что могу указать, что если вы немного ослабите спецификацию, вы можете сделать это в одной строке с splitAsStream.

List<Integer> out = Pattern.compile( "[\\s;]+" ).splitAsStream( line )
       .map( Integer::decode ).collect( Collectors.toList() );

Я использую здесь Integer и Integer::decodeпотому что Byte::decode выдаст ошибку на 0x80, первом входе OP.И вам придется проделать немного больше работы, если вам действительно нужен массив примитивов, но на практике часто подходят чисел в штучной упаковке.

Вот весь код:

public class ScannerStream {

   static String testVector = "//create applet instance\n" +
"0x80 0xB8 0x00 0x00 0x0c 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x00 0x7F;";

   public static void main( String[] args ) {
      List<List<Integer>> commands = new ArrayList<>();
      Scanner fileReader = new Scanner( new StringReader( testVector ) );
      while( fileReader.hasNextLine() ) {
         String line = fileReader.nextLine();
         if( line.startsWith( "0x" ) ) {
            List<Integer> out = Pattern.compile( "[\\s;]+" ).splitAsStream( line )
                    .map( Integer::decode ).collect( Collectors.toList() );
            System.out.println( out );
            commands.add( out );
         }
      }
      System.out.println( commands );
   }
}
0 голосов
/ 11 декабря 2018

Вы на правильном пути.Просто удалите конечный ; и затем используйте методы, предоставленные вам в классе Integer.

while ( fileReader.hasNextLine() ) {
    String line = fileReader.nextLine();
    if ( line.startsWith( "0x" ) ) {
        line = line.replace( ";", "" );
        List<Byte> wrapped = Arrays
                .asList( line.split( " " ) )
                .stream()
                // convert all the string representations to their Int value
                .map( Integer::decode )
                // convert all the Integer values to their byte value
                .map( Integer::byteValue )
                .collect( Collectors.toList() );
        // if you're OK with changing commands to a List<Byte[]>, you can skip this step
        byte[] toAdd = new byte[wrapped.size()];
        for ( int i = 0; i < toAdd.length; i++ ) {
            toAdd[i] = wrapped.get( i );
        }
        commands.add( toAdd );
    }
}
...