我曾经从文本文件中RandomAccessFile读取过byte.
public static void readFile(RandomAccessFile fr) {
byte[] cbuff = new byte[1];
fr.read(cbuff,0,1);
System.out.println(new String(cbuff));
}
Run Code Online (Sandbox Code Playgroud)
为什么我看到一个完整的角色被这个阅读?
Joa*_*uer 114
A char表示Java (*)中的字符.它大2字节(至少是有效值范围所暗示的).
这并不一定意味着字符的每个表示都是2个字节长.实际上,许多编码仅为每个字符保留1个字节(或者对于最常见的字符使用1个字节).
当您调用String(byte[])构造函数时,您要求Java 使用平台默认编码将其转换byte[]为a String.由于平台默认编码通常是1字节编码(如ISO-8859-1)或可变长度编码(如UTF-8),因此可以轻松地将该1字节转换为单个字符.
如果您在使用UTF-16(或UTF-32或UCS-2或UCS-4或...)作为平台默认编码的平台上运行该代码,那么您将无法获得有效的结果(您将获得一个String含有Unicode替换字符代替).
这就是为什么你不应该依赖于平台的默认编码的原因之一:之间进行转换时byte[]和char[]/ String或之间InputStream和Reader之间或OutputStream和Writer,你应该总是指定要使用的编码.如果不这样做,那么您的代码将依赖于平台.
(*)这并不完全正确:a char表示UTF-16码点.任一个或2 UTF-16的码点代表一个Unicode码点.Unicode代码点通常表示一个字符,但有时会使用多个Unicode代码点来组成一个字符.但上面的近似值足以讨论手头的主题.
构造函数String(byte[] bytes)从缓冲区中获取字节并将它们编码为字符.
它使用平台默认字符集将字节编码为字符.如果您知道,您的文件包含在不同的字符集中编码的文本,您可以使用它String(byte[] bytes, String charsetName)来使用正确的编码(从字节到字符).