You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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) {
        // 实现代码
    }
}

几个要注意的点

  1. ByteBuffer容量问题:你用了allocate(1024),如果文件转成字节后超过1024,会直接抛BufferOverflowException。如果不确定文件大小,建议先用ByteArrayOutputStream收集所有字节,最后再转成ByteBuffer,或者用动态扩容的方式。
  2. 线程安全:ByteBuffer不是线程安全的,绝对不能用Files.lines(filePath).parallel().forEach(...),不然会出现数据错乱。
  3. 异常处理:上面的代码省略了异常捕获,你可以根据需求加try-catch处理非法十六进制字符、文件读写错误这些情况。

内容的提问来源于stack exchange,提问作者qdbp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:06:27