Ste*_*fan 1 java file-writing java-io bytestream
这两个行会我写字母A的file。有人能告诉我他们在内部工作上有什么不同吗?
FileOutputStream fileOutputStream = new FileOutputStream("test.txt");
fileOutputStream.write(65);
fileOutputStream.write('A');
Run Code Online (Sandbox Code Playgroud)
[编辑]:我对转换在这两种情况下的工作方式更感兴趣。据我所知,ASCII 和 UNICODE 表是什么。
让我们从开始的javadoc的FileOutputStream。如果你看它,你会发现有三种write方法:
void write?(byte[] b)- 将b.length指定字节数组中的字节写入此文件输出流。void write?(byte[] b, int off, int len)- 将len指定字节数组中的字节从偏移量开始写入off此文件输出流。void write?(int b)- 将指定字节写入此文件输出流。
那么它告诉我们什么呢?
显然,当我们调用fileOutputStream.write(65)or 时fileOutputStream.write('A'),我们不会调用该方法的第一个或第二个重载write。我们实际上是在调用第三个。
因此,当我们调用 时fileOutputStream.write('A'),该char值'A'被转换为一个int值。此转换是从到的原始扩展转换。它相当于做一个显式的类型转换;即。charint(int) 'A'
从整数类型(例如char)到更大的整数类型(例如int)的原始扩展只是使它更大的问题。在这种情况下,我们只在前面添加 16 个零位。(因为char未签名且int已签名。)
当我们查看 ASCII 和 Unicode 代码表时,我们看到它们都对字母大写 A 使用相同的值。它是十进制的 65 或十六进制的 41。换句话说,(int) 'A'和65是相同的值。
因此,当您采用发生的隐式扩展转换, fileOutputStream.write('A')并且fileOutputStream.write(65)实际上write 使用相同的参数 value 进行调用时。
最后,javadoc forwrite(int)指的是这个 javadoc,它说:
将指定的字节写入此输出流。write 的一般约定是将一个字节写入输出流。要写入的字节是参数 b 的低 8 位。b 的 24 个高位被忽略。
这解释了如何int神奇地变成byte.
请注意,这只会打印一些合理的内容,因为我们在 ASCII 字符集中选择了一个字符。碰巧 Unicode 选择将 ASCII 字符集镜像为前 128 个 Unicode 代码点。
如果您替换A为 ASCII 字符集之外的某些字符,则很有可能OutputStream::write(int)会出现乱码。
输出文本时最好使用 aFileWriter而不是 a FileOutputStream。