原文链接 译文链接 译者:沈义扬

字节流和字符流

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

[Google Guava] 9-I/O的更多相关文章

  1. java开发人员,最应该学习和熟练使用的工具类。google guava.(谷歌 瓜娃)

    学习参考文章: http://blog.csdn.net/wisgood/article/details/13297535 http://ifeve.com/google-guava/ http:// ...

  2. [转]Google Guava官方教程(中文版)

    Google Guava官方教程(中文版) http://ifeve.com/google-guava/

  3. Google Guava官方教程(中文版)

    Google Guava官方教程(中文版) 原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库, ...

  4. Google Guava vs Apache Commons for Argument Validation

    It is an established good practice to validate method arguments at the beginning of the method body. ...

  5. 使用 Google Guava 美化你的 Java 代码

    文章转载自:http://my.oschina.net/leejun2005/blog/172328 目录:[ - ] 1-使用 GOOGLE COLLECTIONS,GUAVA,STATIC IMP ...

  6. Google Guava之--cache

    一.简介 Google Guava包含了Google的Java项目许多依赖的库,如:集合 [collections] .缓存 [caching] .原生类型支持 [primitives support ...

  7. Google Guava学习笔记——简介

    Google Guava是什么东西?首先要追溯到2007年的“Google Collections Library”项目,它提供对Java 集合操作的工具类.后来Guava被进化为Java程序员开发必 ...

  8. (翻译)Google Guava Cache

    翻译自Google Guava Cache This Post is a continuation of my series on Google Guava, this time covering G ...

  9. Google Guava官方教程(中文版)地址

    Google Guava官方教程(中文版) http://ifeve.com/google-guava/ 瓜娃啊瓜娃

  10. Google Guava

    公司用到了 Joiner  HashMultimap 等  都是属于Google Guava包中的东西 官方文档 http://ifeve.com/google-guava/ 有时间了整理一下

随机推荐

  1. 龙芯PG10 安装uuid-ossp 的方法 复用瀚高数据库的 so文件

    接着上一篇blog  当时在中标麒麟 龙芯上面安装了postgresql10.10 的版本 但是没搞定 uuid 当时遇到的问题: 0. 只安装postgresql数据库会报错如图示: 我验证了下 安 ...

  2. c# 中对于每次修改的程序 都必须重新手动生成 才能编译的问题

    问题描述:原来用VS2017,升级了VS2019,发现修改了Winform界面,F5运行竟然还是原来的界面 问题解决: 需要修改两个地方 工具>> 选项>> 项目和解决方案&g ...

  3. Jmeter 跨线程组传递参数 之两种方法(转)

    终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为同一个线程组下的请求是同时发送的),只需要发送一次登录请求,请求B直接用登录请求的参数即可,直 ...

  4. Git强制推送代码到多个远程仓库

    git push -f origin master 注释: origin 远程仓库名, master 分支名,-f 为force,意为:强行.强制.

  5. 多文件上传,添加重复文件时无法触发onchange事件。

    <input type="file" id="upload" @change="getFile($event)" multiple=& ...

  6. Calibre 和 Kindle 配合的使用方法

    1. 前言 使用"Calibre"软件,把网上下载的电子书转换成适合kindle阅读的格式. 2. 使用经验总结 2.1 首行缩进.段落间距设置 2.2 输出为mobi格式设置 2 ...

  7. dubbo中使用的zookeeper,netty以及javassist的Demo文件

    javassist测试Demo netty测试Demo zookeeper测试Demo

  8. 关于UBOOT,LINUX内核编译,根文件系统的15个小问题

    (1)内核默认运行地址和加载地址在哪里设置? 由 arch/arm/kernel/vmlinux.lds.S 生成的 arch/armkernel/vmlinux.lds决定   (2)从FLASH什 ...

  9. 并不对劲的THUWC2020

    day -inf 因为一些(不是寒假时长锐减的)小原因,今年(2020)THUWC在去年(2019)就举办了! 这导致某个小弱智只能临阵磨枪了QAQ- day 1 早: 没有看到吕爷,签到.试机. 签 ...

  10. 第八讲,TLS表(线程局部存储)

    一丶复习线程相关知识 首先讲解TLS的时候,需要复习线程相关知识,  (thread local storage ) 1.了解经典同步问题 首先我们先写一段C++代码,开辟两个线程去跑,看看会不会出现 ...