不可预知的FileWriter

时间:2014-10-26 19:22:09

标签: java filewriter

为什么FileWriter写入不同的字节数? FileWriterwrite(int)方法委托给StreamEncoder,但其代码不可用。我知道有不同的编码,但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);
    }
}

记事本在文件中只显示一个符号(如果您注释第三个fos.write,记事本中将有两个符号)。 那么我怎样才能使它工作并明确地读取我的文件呢?

3 个答案:

答案 0 :(得分:1)

漂亮的小谜题!

正在发生的事情是,您提供的int正在转换为char,然后它会通过CharsetEncoder转到int把它变成字节。由于您未指定编码,我强烈怀疑您最终会使用UTF-8。 UTF-8将字符编码为一个,两个或三个字节。

charInteger.MAX_VALUE的转换将为您留下16位无符号值。您可能认为这将被编码为两个字节,但是ASCII字符被编码为UTF-8,这就是为什么最多127个被编码为单个字节的原因。当然,这意味着有些人现在需要两个以上的字节(通过一个简单的计数参数)。当你给它2047时,它设法以UTF-8编码为两个字节;但是你的Integer.MAX_VALUE的最后一个例子被编码为三个。

请注意,char首先被转换为16位无符号StreamEncoder,因此其值实际为65535。

FileWriter的来源似乎尚未正式提供,但它是there if you look for it

Notepad正在做什么,我不知道,但我怀疑它不支持UTF-8。

虽然我试图在这里解释下面发生了什么,但最重要的是你不应该使用{{1}}来写除字符以外的任何内容。

答案 1 :(得分:0)

FileWriter用于编写字符数据。如果要编写二进制数据,请使用DataOutputStream

答案 2 :(得分:0)

实例化FileWriter对象时,默认为平台默认字符编码。 FileWriter的Javadoc说:

  

此类的构造函数假定为默认字符   编码和默认的字节缓冲区大小是可以接受的。要指定   这些值自己,在一个上构造一个OutputStreamWriter   FileOutputStream中。

因此,要设置编码而不是使用FileWriter,请使用其父类 - OutputStreamWriter

FileOutputStream fileStream = new FileOutputStream(new File("out.txt"));
OutputStreamWriter writer = new OutputStreamWriter(fileStream, "UTF-8");