[Google Guava] 9-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优点的初衷。
使用源与汇
一旦有了源与汇的实例,就可以进行若干读写操作。
通用操作
所有源与汇都有一些方法用于打开新的流用于读或写。默认情况下,其他源与汇操作都是先用这些方法打开流,然后做一些读或写,最后保证流被正确地关闭了。这些方法列举如下:
- openStream():根据源与汇的类型,返回InputStream、OutputStream、Reader或者Writer。
- openBufferedStream():根据源与汇的类型,返回InputStream、OutputStream、BufferedReader或者BufferedWriter。返回的流保证在必要情况下做了缓冲。例如,从字节数组读数据的源就没有必要再在内存中作缓冲,这就是为什么该方法针对字节源不返回BufferedInputStream。字符源属于例外情况,它一定返回BufferedReader,因为BufferedReader中才有readLine()方法。
源操作
字节源 | 字符源 |
byte[] read() | String read() |
N/A | ImmutableList<String> readLines() |
N/A | String readFirstLine() |
long copyTo(ByteSink) | long copyTo(CharSink) |
long copyTo(OutputStream) | long copyTo(Appendable) |
long size() (in bytes) | N/A |
boolean isEmpty() | boolean isEmpty() |
boolean contentEquals(ByteSource) | N/A |
HashCode hash(HashFunction) | N/A |
汇操作
字节汇 | 字符汇 |
void write(byte[]) | void write(CharSequence) |
long writeFrom(InputStream) | long writeFrom(Readable) |
N/A | void writeLines(Iterable<? extends CharSequence>) |
N/A | void writeLines(Iterable<? extends CharSequence>, String) |
范例
01
|
//Read the lines of a UTF-8 text file
|
02
|
ImmutableList<String> lines = Files.asCharSource(file, Charsets.UTF_8).readLines();
|
03
|
//Count distinct word occurrences in a file
|
04
|
Multiset<String> wordOccurrences = HashMultiset.create(
|
05
|
Splitter.on(CharMatcher.WHITESPACE)
|
06
|
.trimResults()
|
07
|
.omitEmptyStrings()
|
08
|
.split(Files.asCharSource(file, Charsets.UTF_8).read()));
|
09
|
10
|
//SHA-1 a file
|
11
|
HashCode hash = Files.asByteSource(file).hash(Hashing.sha1());
|
12
|
13
|
//Copy the data from a URL to a file
|
14
|
Resources.asByteSource(url).copyTo(Files.asByteSink(file));
|
文件操作
除了创建文件源和文件的方法,Files类还包含了若干你可能感兴趣的便利方法。
createParentDirs(File) | 必要时为文件创建父目录 |
getFileExtension(String) | 返回给定路径所表示文件的扩展名 |
getNameWithoutExtension(String) | 返回去除了扩展名的文件名 |
simplifyPath(String) | 规范文件路径,并不总是与文件系统一致,请仔细测试 |
fileTreeTraverser() | 返回TreeTraverser用于遍历文件树 |
原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: [Google Guava] 9-I/O
from: http://ifeve.com/google-guava-io/
[Google Guava] 9-I/O相关推荐
- Error:Could not download guava.jar (com.google.guava:guava:19.0): No cached version available for of
今天从git导入demo 报错 Error:Could not download guava.jar (com.google.guava:guava:19.0): No cached version ...
- 为什么我不建议你用阿里巴巴Java规范,而使用 Google Guava 编程?
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来自 | 张丰哲 链接 | www.jianshu.com ...
- 为什么推荐 Java 程序员使用 Google Guava 编程
点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来自 | 张丰哲 链接 | www.jianshu.com/p/97778b21bd00 前言 ...
- [Google Guava] 1.3-常见Object方法
原文链接 译者: 沈义扬 equals 当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查.使用Objects.equal帮助你执行n ...
- Google Guava Collections 使用介绍
原帖http://www.open-open.com/lib/view/open1325143343733.html 简介: Google Guava Collections 是一个对 Java Co ...
- [Google Guava] 3-缓存
原文地址 译文地址 译者:许巧辉 校对:沈义扬 范例 01 LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() ...
- [Google Guava] 11-事件总线
原文链接 译文连接 译者:沈义扬 传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的.设计EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦.EventBus ...
- [Google Guava] 2.4-集合扩展工具类
原文链接 译文链接 译者:沈义扬,校对:丁一 简介 有时候你需要实现自己的集合扩展.也许你想要在元素被添加到列表时增加特定的行为,或者你想实现一个Iterable,其底层实际上是遍历数据库查询的结果集 ...
- [Google Guava] 8-区间
原文链接 译文链接 译文:沈义扬 范例 1 List scores; 2 Iterable belowMedian =Iterables.filter(scores,Range.lessThan(me ...
- [Google Guava] 6-字符串处理:分割,连接,填充
原文链接 译文链接 译者:沈义扬,校对:丁一 连接器[Joiner] 用分隔符把字符串序列连接起来也可能会遇上不必要的麻烦.如果字符串序列中含有null,那连接操作会更难.Fluent风格的Joine ...
最新文章
- Java中 实体类 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念
- amos看拟合度在哪里看_小程序开发公司哪里强?看这几点
- 测试RDA5807收音机模块
- R之ddlpy函数学习[转载]
- Java反射最佳实践
- 41. 包含min函数的栈【单调栈】
- Python 处理server返回gzip内容
- 【android】【转】class android.media.MediaPlayer
- 芯片项目谁支持谁负责 重大损失将予以通报
- 15个基本的C#面试问题
- .net core 源码解析-web app是如何启动并接收处理请求
- jquery简介 each遍历 prop attr
- 曝光原理_泰国精戈咖啡效果反馈 作用原理曝光
- @mapperscan注解_Spring的@Import注解详解
- 【英语】Invest in Yourself
- 文本框输入限制正则表达式收集
- rinetd 安装、配置方法 通过端口转发来访问内网服务
- AB-PLC软件安装以及授权
- 老生常谈之防止刷新重复提交表单。
- CYK 算法 Python 实现
热门文章
- Distributed locks with Redis--官方
- YJango的循环神经网络——实现LSTM YJango的循环神经网络——实现LSTM YJango YJango 7 个月前 介绍 描述最常用的RNN实现方式:Long-Short Term Me
- 用RPython在云端运行可扩展数据科学
- mysql开启定时器_MySQL定时器开启、调用实现代码
- jvm性能调优 - 16案例实战_每日上亿请求量的电商系统 年轻代垃圾回收参数如何优化
- Python-爬取自己博客文章的URL
- 基础JavaScript_Day02
- linux 文件类型 管理,Linux的文件类型及用户管理
- 分布式锁-zk临时节点
- 多线程七种执行的状态