我在读有关InputStream
和InputStreamReader
的文章。
大多数人说InputStream
是字节,而InputStreamReader
是文本。
因此,我创建了一个仅包含一个字符“ a”的简单文件。
当我使用InputStream
读取文件并将其转换为char
时,它会打印字母'a'。当我使用InputStreamReader
做同样的事情时,它也给了我相同的结果。
那么区别在哪里呢?我以为InputStream
不能给字母'a'。
这是否意味着当一个字符有8位时,InputStream
和InputStreamReader
之间没有区别吗?当一个字符有多个byte
时,它们之间是否仅有区别是真的吗?
最佳答案
不,即使是8位字符,InputStream
和InputStreamReader
也不同。
查看不带参数的InputStream
's read()
方法。它返回一个int
,但是根据文档,返回一个字节(范围为0到255),对于EOF为-1。其他读取方法适用于字节数组。InputStreamReader
从Reader
继承。没有参数的Reader
's read()方法也会返回int
。但是这里的int值(范围为0到65535)被解释为字符或EOF为-1。其他读取方法直接与char
数组一起使用。
区别在于编码。 InputStreamReader
的构造函数需要显式编码,或者使用平台的默认编码。编码是字节和字符之间的转换。
您说:“当我使用InputStream读取文件并将其转换为char时,它会打印字母'a'。”因此,您读取了字节并将其手动转换为字符。此转换部分使用翻译编码内置到InputStreamReader
中。
即使对于一个字节的字符集也存在差异。因此,您的示例是字母“ a”,对于Windows ANSI编码,十六进制值为61(在Java中为“ Cp1252”)。但是对于编码IBM-Thai,字节0x61被解释为“ /”。
人民说的没错。 InputStream
用于二进制数据,最重要的是InputStreamReader
用于文本,根据编码在二进制数据和文本之间进行转换。
这是一个简单的示例:
import java.io.*;
public class EncodingExample {
public static void main(String[] args) throws Exception {
// Prepare the byte buffer for character 'a' in Windows-ANSI
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, "Cp1252"));
writer.print('a');
writer.flush();
final byte[] buffer = baos.toByteArray();
readAsBytes(new ByteArrayInputStream(buffer));
readWithEncoding(new ByteArrayInputStream(buffer), "Cp1252");
readWithEncoding(new ByteArrayInputStream(buffer), "IBM-Thai");
}
/**
* Reads and displays the InputStream's bytes as hexadecimal.
* @param in The inputStream
* @throws Exception
*/
private static void readAsBytes(InputStream in) throws Exception {
int c;
while((c = in.read()) != -1) {
final byte b = (byte) c;
System.out.println(String.format("Hex: %x ", b));
}
}
/**
* Reads the InputStream with an InputStreamReader and the given encoding.
* Prints the resulting text to the console.
* @param in The input stream
* @param encoding The encoding
* @throws Exception
*/
private static void readWithEncoding(InputStream in, String encoding) throws Exception {
Reader reader = new InputStreamReader(in, encoding);
int c;
final StringBuilder sb = new StringBuilder();
while((c = reader.read()) != -1) {
sb.append((char) c);
}
System.out.println(String.format("Interpreted with encoding '%s': %s", encoding, sb.toString()));
}
}
输出为:
Hex: 61
Interpreted with encoding 'Cp1252': a
Interpreted with encoding 'IBM-Thai': /
关于java - 当一个字符有8位时,InputStream与InputStreamReader相同吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50304078/