Google_Guava官方教程(中文版)9-I/O
reprint
Fri Oct 01 20:48:00 CST 2010

I/O

字节流和字符流

Guava使用术语”流” 来表示可关闭的,并且在底层资源中有位置状态的I/O数据流。术语”字 节流”指的是InputStream或OutputStream,”字符流”指的是 Reader 或Writer(虽然他们的 接口Readable 和Appendable被更多地用于方法参数)。相应的工具方法分别在ByteStreams 和CharStreams中。大多数Guava流工具一次处理一个完整的流,并且/或者为了效率自己处 理缓冲。还要注意到,接受流为参数的Guava方法不会关闭这个流:关闭流的职责通常属于 打开流的代码块。其中的一些工具方法列举如下:

ByteStreams CharStreams
byte[] toByteArray(InputStream) String toString(Readable)
N/A List<String> readLines(Readable)
long copy(InputStream, OutputStream) long copy(Readable, Appendable)
void readFully(InputStream, byte[]) N/A
void skipFully(InputStream, long) void skipFully(Reader, long)
OutputStream nullOutputStream() Writer nullWriter()

关于InputSupplier 和OutputSupplier要注意:

在ByteStreams、CharStreams以及com.google.common.io包中的一些其他类中,某些方法仍 然在使用 InputSupplier和OutputSupplier接口。这两个借口和相关的方法是不推荐使用的: 它们已经被下面描述的source和sink类 型取代了,并且最终会被移除。

源与汇

通常我们都会创建I/O工具方法,这样可以避免在做基础运算时总是直接和流打交道。例如, Guava有 Files.toByteArray(File) 和Files.write(File, byte[])。然而,流工具方法的 创建经常最终导致散落各处的相似方法,每个方法读取不同类型的源或写入不同类型的汇 [sink]。例如,Guava中的Resources.toByteArray(URL)和Files.toByteArray(File)做了同 样的事情,只不过数据源一个是URL,一个是文件。为了解决这个问题,Guava有一系列关于 源与汇的抽象。源或汇指某个你知道如何从中打开流的资源,比如File或URL。源是可读的, 汇是可写的。此外,源与汇按照字节和字符划分类型。

  字节 字符
ByteSource CharSource
ByteSink CharSink

源与汇API的好处是它们提供了通用的一组操作。比如,一旦你把数据源包装成了 ByteSource,无论它原先的类型是什么,你都得到了一组按字节操作的方法。

创建源与汇

Guava提供了若干源与汇的实现:

字节 字符
Files.asByteSource(File) Files.asCharSource(File, Charset)
Files.asByteSink(File, FileWriteMode…) Files.asCharSink(File, Charset, FileWriteMode…)
Resources.asByteSource(URL) Resources.asCharSource(URL, Charset)
ByteSource.wrap(byte[]) CharSource.wrap(CharSequence)
ByteSource.concat(ByteSource…) CharSource.concat(CharSource…)
ByteSource.slice(long, long) N/A
N/A ByteSource.asCharSource(Charset)
N/A ByteSink.asCharSink(Charset)

此外,你也可以继承这些类,以创建新的实现。

注:把已经打开的流(比如InputStream)包装为源或汇听起来是很有诱惑力的,但是应该 避免这样做。源与汇的实现应该在每次 openStream()方法被调用时都创建一个新的流。始 终创建新的流可以让源或汇管理流的整个生命周期,并且让多次调用openStream()返回 的 流都是可用的。此外,如果你在创建源或汇之前创建了流,你不得不在异常的时候自己保证 关闭流,这压根就违背了发挥源与汇API优点的初衷。

使用源与汇

一旦有了源与汇的实例,就可以进行若干读写操作。

其它文章