转载出处:http://ajoo.iteye.com/blog/737718
其实guava可以看成是支持java5的apache commons之类的项目.
第一第二回讲的主要是集合类的一些最常用的工具. 其实com.google.common.collect里还有很多非常有用的工具, 比如 Ordering , ComparisonChain , Iterables , Multiset , Multimap 等等. 这里有些我们后面还会涉及.小兄弟正在做socket客户服务器通信相关的课程设计, 所以我有点迫不及待先讲讲common.io这个包了. 这里面最有用的, 在我看来, 就是 CharStreams 和 ByteStreams 这两个工具.
大家知道, 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);
如果你还是需要类似于流一样的操作-比如, 输入的行数太多, 不能一下子都读进来, 那么, 还有一个 LineReader 可以用. 用起来类似于:
- LineReader lineReader = new LineReader(reader);
- for (String line = lineReader.readLine(); line != null; line = lineReader.readLine()) {
- System.out.println(line);
- }
其它的one-liner, 包括:
从一个Readable读取所有东西写到一个Appendable里去:
- CharStreams.copy(reader, writer);
从Readable读取所有内容到一个字符串:
- String content = CharStreams.toString(reader);
另外, 写io程序一个最常见的bug, 就是打开东西忘记关了. 或者关的不彻底. 一般来说, 你要开一个InputStream, 肯定要接下来用一个try-finally, 在用完之后调用close()把它关上. OutputStream, Reader, Writer同理.
但是这很麻烦, 而且容易忘. 在java7的 自动资源管理 出来之前, 可以用common.io包定义的InputSupplier, OutputSupplier接口.
原理是, 你实现一个InputSupplier对象, 把"怎样打开这个InputStream/Reader"的逻辑封装在getInput()它的函数里, 然后, 把它传递给CharStreams, ByteStreams相关的API, 比如readLines(), copy()等, 这些API调用你的supplier, 然后做事, 做完之后它把自己屁股擦干净, 把它打开的InputSteam/Reader再关上.
ByteStreams很类似, 不过它是工作在字节流上, 而不关心字符编码问题.
对应于CharStreams.toString(), 是
- byte[] content = ByteStreams.toByteArray(inputStream)
用来把整个InputStream的内容全部一次性读到一个byte[]里面.
对应于CharStreams.copy(), 是
- ByteStreams.copy(inputStream, outputStream);
用来把所有内容从一个InputStream拷贝到另一个OutputStream.
嗯. 以上.