为何使用StandardCharsets.UTF_16BE写入字符串会出现字符间空格?
问题:使用UTF-16BE写入字符串后,字符间出现多余空格的原因?
我尝试用不同编码写入测试字符串时发现结果有差异:用StandardCharsets.UTF_16LE写入"test",结果显示正常;但用StandardCharsets.UTF_16BE写入时,结果变成了" t e s t"(字符间有多余空格)。想知道这是为什么?
附上相关代码:
String filename="C:\\Users\\name\\Downloads\\debugging.txt"; String str="test"; File fl = new File(filename); try { FileOutputStream fos = new FileOutputStream(fl); //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_16LE)); //看似正常 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_16BE)); //出现异常 bw.write(str); } catch (IOException ignored) { //一些操作 }
解答
核心原因:字节顺序解析不匹配,且缺少BOM标识
UTF-16是双字节编码,每个字符用两个字节存储。UTF_16LE是小端序(低字节在前,高字节在后),UTF_16BE是大端序(高字节在前,低字节在后)。
拿字符't'举例,它的Unicode编码是0x0074:- 用UTF-16LE存储时,字节序列是
0x74 0x00 - 用UTF-16BE存储时,字节序列是
0x00 0x74
- 用UTF-16LE存储时,字节序列是
编辑器的默认解析逻辑导致错位
你打开文件的编辑器大概率默认按UTF-16LE(或带BOM的UTF-16)来解析内容。当它读取UTF-16BE写入的字节时,会把每两个字节按小端序拼接成字符:- 原本的
0x00 0x74会被解析成0x7400,这个编码对应的是不可见的空字符(显示出来就像空格);接着下一组字节0x00 0x65被解析成0x6500,同样会出现一个空字符加'e'的错位效果,最终看起来就是字符间多了空格。
- 原本的
UTF-16LE正常的原因
因为编辑器默认按小端序解析,刚好和UTF-16LE的存储顺序匹配,所以每个字符都能被正确识别。解决办法
如果要让UTF-16BE的文件被编辑器正确识别,可以在写入文件开头添加UTF-16BE的BOM(0xFEFF),这样编辑器就能自动识别大端序编码,不会出现解析错位的问题。
内容的提问来源于stack exchange,提问作者newman
相关产品推荐
相关产品推荐

