Java 不可预测的文件编写器
为什么Java 不可预测的文件编写器,java,filewriter,Java,Filewriter,为什么FileWriter写入的字节数不同FileWriter将其write(int)方法委托给streamncoder,但其代码不可用。我知道有不同的编码,但是FileWriter没有提供设置编码的方法。如果FileWriter的行为如此奇怪,为什么要使用它呢 public static void main(String[] args) { try (FileWriter fos = new FileWriter("out.txt")) { fos.write(127)
FileWriter
写入的字节数不同FileWriter
将其write(int)
方法委托给streamncoder
,但其代码不可用。我知道有不同的编码,但是FileWriter
没有提供设置编码的方法。如果FileWriter的行为如此奇怪,为什么要使用它呢
public static void main(String[] args) {
try (FileWriter fos = new FileWriter("out.txt")) {
fos.write(127); //writes 1 byte (for i<128)
fos.write(2047); //writes 2 bytes (for 127<i<2048)
fos.write(Integer.MAX_VALUE); //writes 3 bytes (for 2048<i)
} catch (IOException ex) {
Logger.getLogger(Experiments.class.getName()).log(Level.SEVERE, null, ex);
}
}
publicstaticvoidmain(字符串[]args){
try(FileWriter fos=newfilewriter(“out.txt”)){
fos.write(127);//写入1个字节(对于iFileWriter
用于写入字符数据。如果要写入二进制数据,请使用DataOutputStream
实例化FileWriter
对象时,默认为平台默认字符编码。
FileWriter的Javadoc说:
此类的构造函数假定默认字符
可接受编码和默认字节缓冲区大小。若要指定
您可以自己创建这些值,然后在
FileOutputStream
因此,要设置编码,请使用其父类–OutputStreamWriter
,而不是使用FileWriter
:
FileOutputStream fileStream = new FileOutputStream(new File("out.txt"));
OutputStreamWriter writer = new OutputStreamWriter(fileStream, "UTF-8");
漂亮的小拼图
发生的情况是,您提供的int
正在转换为char
,然后它将通过CharsetEncoder
将其转换为字节。由于您没有指定编码,我强烈怀疑您最终使用的是UTF-8。UTF-8将字符编码为一个、两个或三个字节
从int
到char
的转换将给您留下一个16位的无符号值。您可能会认为这将被编码为两个字节,但ASCII字符的编码方式与UTF-8中的相同,这就是为什么127以下的字符都被编码为一个字节。当然,这意味着一些字符现在需要两个以上的bytes(通过一个简单的计数参数)。当您给它2047时,它设法在UTF-8中编码为两个字节;但是您的最后一个Integer.MAX_VALUE
示例编码为三个字节
请注意,Integer.MAX_VALUE
首先被转换为一个16位无符号char
,因此它的值实际上是65535
streamncoder
的源代码似乎还没有正式提供,但它是免费的
我不知道记事本在做什么,但我怀疑它不支持UTF-8
虽然我在这里试图解释下面发生了什么,但底线是,您不应该使用FileWriter
来编写字符以外的任何东西。阅读文档。您看到的是多字节编码。@SLaks公平地说,他确实试着四处挖掘:他寻找streamncoder
源代码,但可以找不到。谢谢你的回答。我不知道可变宽度编码。我以为它对不同的数字使用不同的编码,但没有提供设置方法,这让我很困惑。