如何通过Java 8流逐行读取文件十六进制字符串并写入ByteBuffer?
兄弟,这个问题我熟!正好帮你把十六进制转字节写入ByteBuffer的逻辑补全,分两种JDK版本场景给你最实用的方案,都是纯JDK实现,不用依赖第三方库:
首先先给你修正现有代码里的小问题:
Files.lines()返回的每一行已经自动去掉了换行符(\n、\r),所以你写的replaceAll("/\\n|\\r/g", "")其实多余,而且正则写法也不对(Java里的replaceAll用的是Java正则语法,不需要开头结尾的/和g修饰符)。如果你的十六进制行里可能混有空格、制表符这类空白字符,建议改成line.replaceAll("\\s", "").toUpperCase()来清理所有空白并统一转大写,这样鲁棒性更强。
方案一:Java 17+ 用HexFormat(最简洁推荐)
Java 17专门引入了HexFormat类,就是用来处理十六进制和字节互转的,代码简洁到离谱,还不容易出错:
import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; import java.util.HexFormat; public class HexToByteBufferDemo { public static void main(String[] args) throws Exception { Path filePath = Path.of("你的文件路径.txt"); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); HexFormat hexFormat = HexFormat.of(); // 默认支持大小写,也可以自定义分隔符(比如如果你的行里有空格分隔的话) Files.lines(filePath) .map(line -> line.replaceAll("\\s", "").toUpperCase()) // 清理空白+统一大写 .filter(line -> !line.isEmpty()) // 跳过空行,避免无效转换 .forEach(cleanedLine -> { byte[] bytes = hexFormat.parseHex(cleanedLine); byteBuffer.put(bytes); // 直接把转换后的字节数组写入ByteBuffer }); // 写完后记得切换到读模式,方便后续读取 byteBuffer.flip(); } }
这个HexFormat.parseHex()会自动帮你把每两位十六进制字符转成一个字节,完全不用你手动循环处理,太省心了。
方案二:Java 8-16 手动实现转换(规避Deprecated API)
如果你的项目还在用Java 8到16,之前常用的DatatypeConverter.parseHexBinary()已经被标记为Deprecated了,所以推荐自己写一个轻量的转换方法,逻辑清晰还没依赖:
先写个工具方法:
private static byte[] hexStringToByteArray(String hexStr) { int strLength = hexStr.length(); // 先校验字符串长度是否为偶数,不然没法两两分组(你可以根据需求调整,比如忽略最后一个字符或者补0) if (strLength % 2 != 0) { throw new IllegalArgumentException("无效的十六进制字符串:长度必须是偶数"); } byte[] result = new byte[strLength / 2]; for (int i = 0; i < strLength; i += 2) { // 把两位十六进制字符转成对应的字节:高4位+低4位 int highNibble = Character.digit(hexStr.charAt(i), 16); int lowNibble = Character.digit(hexStr.charAt(i + 1), 16); // 强转byte是安全的,因为两位十六进制最大是0xFF,对应int的255,转成byte是-1,但ByteBuffer存的是原始字节数据,不影响后续读取 result[i / 2] = (byte) ((highNibble << 4) | lowNibble); } return result; }
然后把这个方法套进你的代码里:
import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; public class HexToByteBufferDemo { public static void main(String[] args) throws Exception { Path filePath = Path.of("你的文件路径.txt"); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); Files.lines(filePath) .map(line -> line.replaceAll("\\s", "").toUpperCase()) .filter(line -> !line.isEmpty()) .forEach(cleanedLine -> { byte[] bytes = hexStringToByteArray(cleanedLine); byteBuffer.put(bytes); }); byteBuffer.flip(); } // 上面的hexStringToByteArray方法 private static byte[] hexStringToByteArray(String hexStr) { // 实现代码 } }
几个要注意的点
- ByteBuffer容量问题:你用了
allocate(1024),如果文件转成字节后超过1024,会直接抛BufferOverflowException。如果不确定文件大小,建议先用ByteArrayOutputStream收集所有字节,最后再转成ByteBuffer,或者用动态扩容的方式。 - 线程安全:
ByteBuffer不是线程安全的,绝对不能用Files.lines(filePath).parallel().forEach(...),不然会出现数据错乱。 - 异常处理:上面的代码省略了异常捕获,你可以根据需求加
try-catch处理非法十六进制字符、文件读写错误这些情况。
内容的提问来源于stack exchange,提问作者qdbp
相关产品推荐
相关产品推荐

