Reputation: 2108
I have a file which consists of comments (look like Java single-line comments which start with double slash, //
) and space-separated hex values.
File looks like this:
//create applet instance
0x80 0xB8 0x00 0x00 0x0c 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x00 0x7F;
How can I convert line where hex values go from string to byte array?
I use the following approach:
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());
}
}
But definitely, this shows a byte representation of symbols as they were chars and doesn't convert it to byte. That's right. But how can it be converted properly?
Thanks in advance.
Upvotes: 2
Views: 1047
Reputation: 2524
You're on the right track. Just remove the trailing ;
and then use the methods provided for you in the Integer
class.
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 );
}
}
Upvotes: 2
Reputation: 11030
Just thought I'd point out that if you loosen the specification a little bit, you can essentially do this in one line with splitAsStream
.
List<Integer> out = Pattern.compile( "[\\s;]+" ).splitAsStream( line )
.map( Integer::decode ).collect( Collectors.toList() );
I use Integer here and Integer::decode
because Byte::decode
will throw an error on 0x80
, the OP's first input. And you'd have to do a bit more work if you really need an array of primitives, but often boxed numbers will do in practice.
Here's the whole code:
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 );
}
}
Upvotes: 1