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

Java中通过String处理原始字节异常:0x98被替换为'?'

问题原因及解决方案

核心原因

String是Java专门用来存文本字符的类型,压根不是给原始二进制字节用的。把byte[]转成String时,JVM会用系统默认的字符编码(比如UTF-8、GBK)去解码字节序列,要是某个字节在当前编码里属于无效序列(比如0x98在UTF-8里就是非法的单字节),JVM就会把这个字节直接替换成?(ASCII码0x3f),这就是你看到0x98变问号的根源。之后再把String转回字节数组时,?对应的就是0x3f,原始的0x98自然找不回来了。

你的代码问题点

String str = new String(arr); // 用默认编码解码,无效字节被替换成?
out.write(str.getBytes());    // 把?编码成0x3f写入文件

正确处理方式

  1. 直接用byte[]处理二进制数据:如果只是读写二进制文件,完全没必要转成String,直接操作字节数组就行:

    import java.io.*;
    
    public final class StringRawTest {
        public static final void main(String[] args) throws Exception {
            InputStream in = new FileInputStream("symbol_matrix.bin");
            byte[] arr = new byte[in.available()];
            in.read(arr);
            in.close();
            
            OutputStream out = new FileOutputStream("symbol_matrix_output.bin");
            out.write(arr); // 直接写入原始字节数组
            out.close();
        }
    }
    
  2. 在JTextArea中展示原始字节:如果要在文本框里显示二进制数据,得把每个字节转成可读格式,比如十六进制字符串:

    // 将byte[]转为十六进制字符串
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString();
    }
    
    // 使用示例:
    JTextArea textArea = new JTextArea();
    textArea.setText(bytesToHex(arr));
    

    这样既能直观看到原始字节值,又不会丢数据。要是需要从编辑后的文本转回字节,再解析十六进制字符串就行。

内容的提问来源于stack exchange,提问作者BHms game Java

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:40:06