瓜娃之走马观花 (3) - CharStreams和ByteStreams

其实guava可以看成是支持java5的apache commons之类的项目.
第一第二回讲的主要是集合类的一些最常用的工具. 其实com.google.common.collect里还有很多非常有用的工具, 比如[url=http://guava-libraries.googlecode.com/svn/tags/release05/javadoc/com/google/common/collect/Ordering.html]Ordering[/url], [url=http://guava-libraries.googlecode.com/svn/tags/release05/javadoc/com/google/common/collect/ComparisonChain.html]ComparisonChain[/url], [url=http://guava-libraries.googlecode.com/svn/tags/release05/javadoc/com/google/common/collect/Iterables.html]Iterables[/url], [url=http://guava-libraries.googlecode.com/svn/tags/release05/javadoc/com/google/common/collect/Multiset.html]Multiset[/url], [url=http://guava-libraries.googlecode.com/svn/tags/release05/javadoc/com/google/common/collect/Multimap.html]Multimap[/url]等等. 这里有些我们后面还会涉及.

小兄弟正在做socket客户服务器通信相关的课程设计, 所以我有点迫不及待先讲讲common.io这个包了. 这里面最有用的, 在我看来, 就是[url=http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/io/CharStreams.html]CharStreams[/url]和[url=http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/io/ByteStreams.html]ByteStreams[/url]这两个工具.

大家知道, Java里读外设主要是跟InputStream和Reader打交道. 其中InputStream用来读取原始的字节流, 而Reader是在你已经知道了输入是用什么字符集编码的情况下读取字符串.

但是这两个类还是相对底层了一些. 在做一些很灵活复杂的事情的时候是必要的, 甚至我们还需要抬出nio这个大杀器. 可它们对日常工作中一些简单的事情, 就有炮弹打蚊子的感觉.

比如, 我需要从一个Reader里一行一行读出所有文本. 直接用Reader的话, 你需要弄一个BufferedReader, 然后循环调用readLine(), 直到全部读完. 类似这样:

BufferedReader buffered = new BufferedReader(reader);
List<String> lines = new ArrayList<String>();
for (;;) {
String line = buffered.readLine();
if (line == null) {
break;
}
lines.add(line);
}


用CharStreams的话, 一句话就搞定了:
List<String> lines = CharStreams.readLines(reader);


如果你还是需要类似于流一样的操作-比如, 输入的行数太多, 不能一下子都读进来, 那么, 还有一个[url=http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/io/LineReader.html]LineReader[/url]可以用. 用起来类似于:
[code]
LineReader lineReader = new LineReader(reader);
for (String line = lineReader.readLine(); line != null; line = lineReader.readLine()) {
System.out.println(line);
}
[/code]


其它的one-liner, 包括:
从一个Readable读取所有东西写到一个Appendable里去:
[code]CharStreams.copy(reader, writer);[/code]
从Readable读取所有内容到一个字符串:
[code]String content = CharStreams.toString(reader);[/code]

另外, 写io程序一个最常见的bug, 就是打开东西忘记关了. 或者关的不彻底. 一般来说, 你要开一个InputStream, 肯定要接下来用一个try-finally, 在用完之后调用close()把它关上. OutputStream, Reader, Writer同理.

但是这很麻烦, 而且容易忘. 在java7的[url=http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000011.html]自动资源管理[/url]出来之前, 可以用common.io包定义的InputSupplier, OutputSupplier接口.

原理是, 你实现一个InputSupplier对象, 把"怎样打开这个InputStream/Reader"的逻辑封装在getInput()它的函数里, 然后, 把它传递给CharStreams, ByteStreams相关的API, 比如readLines(), copy()等, 这些API调用你的supplier, 然后做事, 做完之后它把自己屁股擦干净, 把它打开的InputSteam/Reader再关上.

ByteStreams很类似, 不过它是工作在字节流上, 而不关心字符编码问题.
对应于CharStreams.toString(), 是[code]byte[] content = ByteStreams.toByteArray(inputStream)[/code]
用来把整个InputStream的内容全部一次性读到一个byte[]里面.

对应于CharStreams.copy(), 是[code]ByteStreams.copy(inputStream, outputStream);[/code]
用来把所有内容从一个InputStream拷贝到另一个OutputStream.


嗯. 以上.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值