1.InputStreamReader
类
流的另一个有趣的特性是您可以将多个流组合成链。一个流不仅可以从它的内部数据源中读取数据,还可以从另一个流中读取数据。
这是 Java 中一种非常强大的机制,它可以通过将一个流连接到另一个流来创建复杂的数据读取场景。这样的方案看起来像这样:
当程序从数据流中读取数据时,数据流又从其数据源(例如另一个数据流或文件)中读取数据。
更重要的是,每个数据流不仅可以读入和发出数据,还可以对其进行转换或对其进行各种操作。这种“中间流”的一个很好的例子就是类InputStreamReader
。
我们已经知道一个名为的类FileReader
——它是一个Reader
从文件中读取数据的类。从哪里InputStreamReader
获取数据?没错——来自InputStream
.
当你创建一个InputStreamReader
对象时,你需要传入一个InputStream
对象或者它的一个子类。例子:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
该类InputStreamReader
具有该类所具有的所有方法Reader
,并且它们以完全相同的方式工作。
InputStreamReader
类和类之间的主要区别FileReader
在于它们从何处读取数据。FileReader
从文件中读取数据(呃——这就是它被称为 的原因FileReader
),InputStreamReader
但从InputStream
.
FileReader
当您使用该方法从对象中读取一个字符时read()
,它会依次从磁盘上的文件中读取两个字节并将它们作为chars
.
InputStreamReader
当您使用该方法从对象中读取一个字符时read()
,它会依次从FileInputStream
传递给它的对象中读取两个字节,然后再从文件中读取数据。结果是对方法的调用链read()
。
2.BufferedReader
类
您可能会经常使用的另一个有趣的类是BufferedReader
. 这也是从另一个流读取数据的“中间流”。
顾名思义,该类BufferedReader
是 的子类Reader
,可让您阅读 characters。但最有趣的是,您还需要以流的形式向它传递一个数据源,可以从中读取字符,即继承该类的流Reader
。
重点是什么?与 不同InputStreamReader
,该类BufferedReader
不会将字节转换为字符:它根本不会转换任何内容。相反,它缓冲数据。
当程序从BufferedReader
对象中读取单个字符时,该对象会同时从其源流中读取大量字符。并将它们存储在内部。
当从对象中读取下一个字符时BufferedReader
,它只是从其内部缓冲区数组中获取下一个字符并返回它,而无需访问数据源。只有当缓冲区中的所有字符都用完时,它才会读入另一个大字符数组。
该类BufferedReader
还有一个非常有用的方法 — String readLine()
,它可以让您一次从源流中读取整个数据字符串。例如,您可以使用此方法读取文件并将其内容逐行显示在屏幕上。例子:
我们专门写了一些紧凑的代码来说明这有多方便。这段代码也可以写得更详细一点。
|
创建一个FileReader 对象。数据源是一个文件。创建一个 BufferedReader 对象。数据源是一个FileReader . 只要阅读器中还有数据 读取一行 显示该行 |
如果将多个流链接在一起,则只close()
需要在其中一个上调用该方法。该流将在其数据源上调用该方法,依此类推,直到close()
在最终数据流上被调用。
3.从控制台读取
还有一个更有趣的事实:该类Scanner
只不过是一个从 中读取数据的中间输入流System.in
,它也是一个数据流。
以下是从控制台读取一行的两种方法:
扫描仪类 | BufferedReader 和 BufferedWriter 类 |
---|---|
|
|
我们的朋友只不过是类的静态变量。这是一个名字是。System.in
in
System
InputStream
in
因此,几乎从您在 CodeGym 上学习 Java 的一开始,您就一直在处理数据流并从中构建链。但现在你会更有意识地去做。
GO TO FULL VERSION