为什么FileWriter
写入不同的字节数? FileWriter
将write(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,记事本中将有两个符号)。 那么我怎样才能使它工作并明确地读取我的文件呢?
答案 0 :(得分:1)
漂亮的小谜题!
正在发生的事情是,您提供的int
正在转换为char
,然后它会通过CharsetEncoder
转到int
把它变成字节。由于您未指定编码,我强烈怀疑您最终会使用UTF-8。 UTF-8将字符编码为一个,两个或三个字节。
从char
到Integer.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");