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写入文件
正确处理方式
直接用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(); } }在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
相关产品推荐
相关产品推荐

