1. 概述
在这篇文章中,我们将探讨InputStream
类以及它如何处理来自不同源的二进制信息。我们还将讨论InputStreamReader
类,并与InputStream
进行比较。
2. InputStream
是什么?
InputStream
是一个类,它从源读取以字节形式存在的二进制数据。由于它是抽象类,我们只能通过其子类,如FileInputStream
和ByteArrayInputStream
等,来实例化它。
3. InputStreamReader
是什么?
相比InputStream
类,InputStreamReader
直接处理字符或文本。它使用给定的InputStream
读取字节,然后根据特定的字符集(Charset)将它们转换为字符。我们可以明确设置字符集,例如UTF-8、UTF-16等,也可以依赖JVM的默认字符集:
@Test
public void givenAStringWrittenToAFile_whenReadByInputStreamReader_thenShouldMatchWhenRead(@TempDir Path tempDir) throws IOException {
String sampleTxt = "Good day. This is just a test. Good bye.";
Path sampleOut = tempDir.resolve("sample-out.txt");
List<String> lines = Arrays.asList(sampleTxt);
Files.write(sampleOut, lines);
String absolutePath = String.valueOf(sampleOut.toAbsolutePath());
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(absolutePath), StandardCharsets.UTF_8)) {
boolean isMatched = false;
int b;
StringBuilder sb = new StringBuilder();
while ((b = reader.read()) != -1) {
sb.append((char) b);
if (sb.toString().contains(sampleTxt)) {
isMatched = true;
break;
}
}
assertThat(isMatched).isTrue();
}
}
上面的代码示例展示了如何使用StandardCharsets.UTF_8
常量来显式设置InputStreamReader
的编码。
我们的FileInputStream
,即InputStream
的一种类型,被InputStreamReader
包装。因此,我们可以看到InputStreamReader
将InputStream
解释为文本,而不是原始字节信息。
4. InputStreamReader
与InputStream
InputStreamReader
是字节流到字符流的桥梁。这个类接受一个InputStream
实例,读取字节,并使用字符编码将其解码。它有一个read()
方法,用于读取单个字符。此方法通过在其底层InputStream
当前位置之前读取一或多个字节来将字节转换为字符。当到达流的末尾时,它返回-1。
相比之下,InputStream
是所有表示字节输入流的类的超类。InputStreamReader
的构造函数的主要参数就是InputStream
,这意味着InputStream
的所有子类都是InputStreamReader
的有效字节源。
InputStream
类也有一个read()
方法,用于读取单个字节。然而,InputStream.read()
方法并不解码字节为字符,而InputStreamReader.read()
则会。
5. 总结
在这篇文章中,我们讨论了InputStream
和InputStreamReader
。InputStream
是一个抽象类,拥有多个子类,专门针对特定形式的二进制数据,如FileInputStream
和ByteArrayInputStream
等。相反,InputStreamReader
从InputStream
读取字节并将其转换为指定编码的字符。
这两个类之间的区别很简单。当我们需要处理二进制数据时,应使用InputStream
。如果需要处理字符流,使用InputStreamReader
可能会有帮助。
创建InputStreamReader
时,InputStream
是主要的构造参数。
文章中使用的所有代码示例可在GitHub上找到。