Java IO:流
Java IO流是我们可以读取或者写入的数据流。如Java IO概述中所述,流通常连接到数据源或者数据目标,例如文件或者网络连接。
流不像数组那样具有读取或者写入数据的索引的概念。通常,我们也不能像在数组中或者在使用RandomAccessFile
的文件中那样在流中来回移动。流只是连续的数据流。
一些流实现(例如" PushbackInputStream")允许我们将数据推回到流中,以便稍后再次读取。但是我们只能回送有限数量的数据,并且不能像遍历数组那样随意遍历数据。数据只能顺序访问。
Java IO流通常基于字节或者基于字符。基于字节的流通常被称为带有"流"的东西,例如InputStream或者OutputStream。这些流一次读取和写入一个原始字节," DataInputStream"和" DataOutputStream"除外,它们也可以读取和写入" int"," long"," float"和" double"值。
基于字符的流通常称为带有"阅读器"或者"书写器"的内容。基于字符的流可以读取/写入字符(如Latin1或者UNICODE字符)。有关基于字符的输入和输出的更多信息,请参见文本Java Readers and Writers。
输入流
类java.io.InputStream是所有Java IO输入流的基类。如果我们正在编写需要从流中读取输入的组件,请尝试使我们的组件依赖于InputStream而不是其任何子类(例如FileInputStream)。这样做使代码能够使用所有类型的输入流,而不仅是具体的子类。
但是,并非总是可能仅依赖于InputStream。如果我们需要能够将数据推回流中,则必须依赖于" PushbackInputStream",这意味着流变量将是这种类型。否则,代码将无法在PushbackInputStream
上调用unread()
方法。
通常,我们可以通过调用read()方法从InputStream读取数据。 read()方法返回一个包含读取的字节的字节值的int。如果没有更多的数据要读取,则read()
方法通常返回-1;否则,方法将返回-1.
这是一个简单的示例:
InputStream input = new FileInputStream("c:\data\input-file.txt"); int data = input.read(); while(data != -1){ data = input.read(); }
输出流
类java.io.OutputStream是所有Java IO输出流的基类。如果我们正在编写需要将输出写入流的组件,请尝试确保该组件依赖于OutputStream
而不是其子类之一。
这是一个简单的示例,将一些数据推送到文件中:
OutputStream output = new FileOutputStream("c:\data\output-file.txt"); output.write("Hello World".getBytes()); output.close();
合并流
我们可以将流组合成链,以实现更高级的输入和输出操作。例如,一次从文件读取每个字节很慢。从磁盘读取较大的数据块,然后逐字节遍历该块字节,速度更快。为了实现缓冲,我们可以将InputStream软件包在BufferedInputStream中。这是一个例子:
InputStream input = new BufferedInputStream( new FileInputStream("c:\data\input-file.txt")); ...
缓冲也可以应用于" OutputStream",从而将对磁盘(或者基础流)的写操作按较大的块进行批处理。这也提供了更快的输出。这是通过BufferedOutputStream
完成的。
缓冲只是通过组合流可以实现的效果之一。我们也可以将InputStream封装在PushbackStream中。这样,我们可以将数据推回到流中,以便稍后重新读取。有时在解析过程中很方便。或者,我们可以使用SequenceInputStream
将两个InputStream
合并为一个
通过将输入和输出流组合成链,还可以实现其他几种效果。我们甚至可以编写自己的流类来包装Java随附的标准流类。这样,我们可以创建自己的效果或者滤镜。