为何FileWriter仅写入单字节?与DataOutputStream的writeChars差异解析
为什么DataOutputStream.writeChars写出带空格的字符,而FileWriter不会?
核心差异原因
1. DataOutputStream.writeChars的本质
DataOutputStream是专门用来写入Java基本类型二进制数据的字节流,writeChars(String s)的逻辑很直接:遍历字符串里的每个char,把每个char以UTF-16双字节的形式写入文件。
Java里的char是16位的,比如字符'A'的Unicode值为U+0041,对应的UTF-16字节是0x00 0x41。文本编辑器打开文件时,0x00属于不可打印的空字符,通常会用空格占位显示,所以最终看到的就是"A B C"。
对应的代码示例:
DataOutputStream dos = new DataOutputStream(new FileOutputStream(my_file)); dos.writeChars("ABC");
这段代码写入的字节序列为:0x00 0x41 0x00 0x42 0x00 0x43。
2. FileWriter的本质
FileWriter是面向文本内容的字符流,默认使用当前平台的字符编码(比如Windows的GBK、Mac/Linux的UTF-8)处理字符转换。
对于'A'-'Z'这类ASCII范围内的字符,在常见编码格式里都仅占用1字节。FileWriter会把Java的char(UTF-16编码)转换成目标编码的字节序列,ASCII字符转换后就是单字节,因此写入文件后,编辑器打开显示的就是连续的"ABC"。
对比FileOutputStream的示例:
FileOutputStream fos = new FileOutputStream(my_file); fos.write("ABC".getBytes());
这段代码直接把字符串按平台编码转成单字节数组写入,效果和FileWriter一致,因为二者底层用了相同的编码转换逻辑。
FileWriter如何实现单字节写入?
FileWriter本身不直接处理字节,核心转换逻辑依赖底层的OutputStreamWriter:
- 调用
write方法时,先将字符串的UTF-16char序列,转换成目标编码的字节数组。 - 只要字符在目标编码中支持单字节表示(比如ASCII字符),转换后就输出单字节;如果是中文这类超出ASCII范围的字符,会按对应编码规则转成多字节——这是编码本身的特性,而非FileWriter的限制。
内容的提问来源于stack exchange,提问作者Ahmet Cicek
相关产品推荐
相关产品推荐

