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个字节(对于i
FileWriter
用于写入字符数据。如果要写入二进制数据,请使用
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
源代码,但可以找不到。谢谢你的回答。我不知道可变宽度编码。我以为它对不同的数字使用不同的编码,但没有提供设置方法,这让我很困惑。