Guava的I/O平时使用不太多,目前项目原因导致基本上只有在自己写一些文本处理小工具才用得到。但是I/O始终是程序猿最常遇到的需求和面试必问的知识点之一。同时Guava的I/O主要面向是时JDK5和JDK6的时候的设计,现在已经到了JDK8,然而由于懒惰并没有仔细研究这之间的差别,反正就慢慢看吧。

Guava提供了一个Files的类,用final修饰了,所以直接用就行了,也不要再想着扩展了,里面的方法很多:

获得一个BufferedReader/bufferedwriter,简单就是从file->fileinputstream->inputstreamreader-bufferedreader,一路生成过去:

 public static BufferedReader newReader(File file, Charset charset)
throws FileNotFoundException {
checkNotNull(file);
checkNotNull(charset);
return new BufferedReader(
new InputStreamReader(new FileInputStream(file), charset));
}
  public static BufferedWriter newWriter(File file, Charset charset)
throws FileNotFoundException {
checkNotNull(file);
checkNotNull(charset);
return new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file), charset));
}

获得一个Guava自定义的ByteSource对象:

public static ByteSource asByteSource(File file) {
return new FileByteSource(file);
}

这个FileByteSource其实就是提供了获得文件流、文件大小、获得字节数组、toString()等方法。

获得一个Guava自定义的ByteSink对象:

 public static ByteSink asByteSink(File file, FileWriteMode... modes) {
return new FileByteSink(file, modes);
}

ByteSink的概念稍微有点绕,看下源码:

private static final class FileByteSink extends ByteSink {

    private final File file;
private final ImmutableSet<FileWriteMode> modes; private FileByteSink(File file, FileWriteMode... modes) {
this.file = checkNotNull(file);
this.modes = ImmutableSet.copyOf(modes);
} @Override
public FileOutputStream openStream() throws IOException {
return new FileOutputStream(file, modes.contains(APPEND));
} @Override
public String toString() {
return "Files.asByteSink(" + file + ", " + modes + ")";
}
}

就是给你一个对象,然后这个对象可以将内容追加到file里面去,它可以提供对该文件的追加操作的输出流。

接下来又是一对输入输出的Char对象:

 public static CharSource asCharSource(File file, Charset charset) {
return asByteSource(file).asCharSource(charset);
}
public static CharSink asCharSink(File file, Charset charset,
FileWriteMode... modes) {
return asByteSink(file, modes).asCharSink(charset);
}

输入对象提供了比如readlines()、concat组合两个sources并返回组合后的内容。

输出对象提供了比如获得writer、writelines等内容。

接下来的几个方法可能是更常用和方便的方法了。

获得字节数组:

  public static byte[] toByteArray(File file) throws IOException {
return asByteSource(file).read();
}

获得文件内容的String对象:

  public static String toString(File file, Charset charset) throws IOException {
return asCharSource(file, charset).read();
}

为文件写入一个字节数组的内容:

  public static void write(byte[] from, File to) throws IOException {
asByteSink(to).write(from);
}

把一个文件内容拷贝到一个输出流中:

  public static void copy(File from, OutputStream to) throws IOException {
asByteSource(from).copyTo(to);
}

把一个文件拷贝到另外一个地方:

  public static void copy(File from, File to) throws IOException {
checkArgument(!from.equals(to),
"Source %s and destination %s must be different", from, to);----------两个文件必须不同
asByteSource(from).copyTo(asByteSink(to));
}

把一个字符序列写入文件:

 public static void write(CharSequence from, File to, Charset charset)
throws IOException {
asCharSink(to, charset).write(from);
}

把一个文件拷贝追加后另外一个文件后面:

 public static void copy(File from, Charset charset, Appendable to)
throws IOException {
asCharSource(from, charset).copyTo(to);
}

判断两个文件是否一致:

 public static boolean equal(File file1, File file2) throws IOException {
checkNotNull(file1);
checkNotNull(file2);
if (file1 == file2 || file1.equals(file2)) {
return true;
} /*
* Some operating systems may return zero as the length for files
* denoting system-dependent entities such as devices or pipes, in
* which case we must fall back on comparing the bytes directly.
*/
long len1 = file1.length();
long len2 = file2.length();
if (len1 != 0 && len2 != 0 && len1 != len2) {-------------考虑到操作系统级别的不同,仅仅length并不完整
return false;
}
return asByteSource(file1).contentEquals(asByteSource(file2));
}

创建一个临时目录((-__-)b,这个方法有什么用吗?):

 public static File createTempDir() {
File baseDir = new File(System.getProperty("java.io.tmpdir"));
String baseName = System.currentTimeMillis() + "-"; for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
File tempDir = new File(baseDir, baseName + counter);
if (tempDir.mkdir()) {
return tempDir;
}
}
throw new IllegalStateException("Failed to create directory within "
+ TEMP_DIR_ATTEMPTS + " attempts (tried "
+ baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
}

创建一个文件(如果不存在)或者修改一下该文件的末次修改时间(如果已经存在),就相当于linux的touch命令:

  public static void touch(File file) throws IOException {
checkNotNull(file);
if (!file.createNewFile()
&& !file.setLastModified(System.currentTimeMillis())) {
throw new IOException("Unable to update modification time of " + file);
}

为要创建的文件创建路径中出现的其他父文件夹路径然后创建这个File,需要其中某一步执行失败,可以会已经创建了一些父文件夹出来而无法收回:

 public static void createParentDirs(File file) throws IOException {
checkNotNull(file);
File parent = file.getCanonicalFile().getParentFile();
if (parent == null) {--------本身就是根目录
return;
}
parent.mkdirs();
if (!parent.isDirectory()) {
throw new IOException("Unable to create parent directories of " + file);
}
}

移动文件:

  public static void move(File from, File to) throws IOException {
checkNotNull(from);
checkNotNull(to);
checkArgument(!from.equals(to),
"Source %s and destination %s must be different", from, to); if (!from.renameTo(to)) {
copy(from, to);
if (!from.delete()) {
if (!to.delete()) {
throw new IOException("Unable to delete " + to);
}
throw new IOException("Unable to delete " + from);
}
}
}

只读第一行:

  public static String readFirstLine(File file, Charset charset)
throws IOException {
return asCharSource(file, charset).readFirstLine();
}

用的最多的一个方法,把文件转成一个List<String>:

public static List<String> readLines(File file, Charset charset)
throws IOException {
// don't use asCharSource(file, charset).readLines() because that returns
// an immutable list, which would change the behavior of this method
return readLines(file, charset, new LineProcessor<List<String>>() {
final List<String> result = Lists.newArrayList(); @Override
public boolean processLine(String line) {
result.add(line);
return true;
} @Override
public List<String> getResult() {
return result;
}
});
}

返回你定义格式的内容,需要提供一个回掉函数,回掉函数可以返回一个fboolean,如果返回false就结束读取,也就是你可以在这里去自定义自己想要的结束位置:

  public static <T> T readLines(File file, Charset charset,
LineProcessor<T> callback) throws IOException {
return asCharSource(file, charset).readLines(callback);
}
  public static <T> T readBytes(File file, ByteProcessor<T> processor)
throws IOException {
return asByteSource(file).read(processor);
}

返回一个文件的Hash值,你可以自定义hash算法:

  public static HashCode hash(File file, HashFunction hashFunction)
throws IOException {
return asByteSource(file).hash(hashFunction);
}

将文件内容全量映射到内存中,就是JDK1.4以后NIO里面独立于JVM堆之外的直接内存,用于加速IO处理的:

  public static MappedByteBuffer map(File file, MapMode mode)
throws IOException {
checkNotNull(file);
checkNotNull(mode);
if (!file.exists()) {
throw new FileNotFoundException(file.toString());
}
return map(file, mode, file.length());
}
  public static MappedByteBuffer map(File file, MapMode mode, long size)
throws FileNotFoundException, IOException {
checkNotNull(file);
checkNotNull(mode); Closer closer = Closer.create();
try {
RandomAccessFile raf = closer.register(
new RandomAccessFile(file, mode == MapMode.READ_ONLY ? "r" : "rw"));
return map(raf, mode, size);
} catch (Throwable e) {
throw closer.rethrow(e);
} finally {
closer.close();
}
}

返回准确的文件路径:

 public static String simplifyPath(String pathname) {
checkNotNull(pathname);
if (pathname.length() == 0) {
return ".";
} // split the path apart
Iterable<String> components =
Splitter.on('/').omitEmptyStrings().split(pathname);
List<String> path = new ArrayList<String>(); // resolve ., .., and //
for (String component : components) {
if (component.equals(".")) {
continue;
} else if (component.equals("..")) {
if (path.size() > 0 && !path.get(path.size() - 1).equals("..")) {
path.remove(path.size() - 1);
} else {
path.add("..");
}
} else {
path.add(component);
}
} // put it back together
String result = Joiner.on('/').join(path);
if (pathname.charAt(0) == '/') {
result = "/" + result;
} while (result.startsWith("/../")) {
result = result.substring(3);
}
if (result.equals("/..")) {
result = "/";
} else if ("".equals(result)) {
result = ".";
} return result;
}

Guava包学习---I/O的更多相关文章

  1. Guava包学习---Lists

    Guava包是我最近项目中同事推荐使用的,是google推出的库.里面的功能非常多,包括了集合.缓存.原生类型支持.并发库.通用注解.字符串处理.IO等.我们项目中使用到了guava依赖,但是实际上只 ...

  2. Guava包学习--EventBus

    之前没用过这个EventBus,然后看了一下EventBus的源码也没看明白,(-__-)b.反正大概就是弄一个优雅的方式实现了观察者模式吧.慢慢深入学习一下. 观察者模式其实就是生产者消费者的一个变 ...

  3. Guava包学习-Cache

    这段时间用到了ehcache和memcache,memcache只用来配置在tomcat中做负载均衡过程中的session共享,然后ehcache用来存放需要的程序中缓存. Guava中的Cache和 ...

  4. Guava包学习---Maps

    Maps包方法列表: 还是泛型创建Map: public static <K, V> HashMap<K, V> newHashMap() { return new HashM ...

  5. Guava包学习--Hash

    我们HashMap会有一个rehash的过程,为什么呢?因为java内建的散列码被限制为32位,而且没有分离散列算法和所作用的数据,所以替代算法比较难做.我们使用HashMap的时候它自身有一个reh ...

  6. Guava包学习---Bimap

    Bimap也是Guava中提供的新集合类,别名叫做双向map,就是key->value,value->key,也就是你可以通过key定位value,也可以用value定位key. 这个场景 ...

  7. Guava包学习-Multimap

    它和上一章的MultiSet的继承结果很相似,只不过在上层的接口是Multimap不是Multiset. Multimap的特点其实就是可以包含有几个重复Key的value,你可以put进入多个不同v ...

  8. Guava包学习---Sets

    Sets包的内容和上一篇中的Lists没有什么大的区别,里面有些细节可以看一下: 开始的创建newHashSet()的各个重载方法.newConcurrentHashSet()的重载方法.newTre ...

  9. Guava包学习--Table

    Table,顾名思义,就好像HTML中的Table元素一样,其实就是行+列去确定的值,更准确的比喻其实就是一个二维矩阵. 其实它就是通过行+列两个key去找到一个value,然后它又containsv ...

随机推荐

  1. web弹出对话框

    Page.ClientScript.RegisterStartupScript(this.GetType(), "", "<script>alert('请输入 ...

  2. 关于UI回调Invoker的实现(一)

    打算写一个DirectUI库,在写其中底层窗口的回调构造的时候遇到一个问题. Invoker是一个模板,因为closure的关系,它必须保存一个类对象的指针,和回调函数的地址.而函数调用的时候,就可以 ...

  3. 第8天:javascriptDOM小 案例、onmouseover 、onmouseout

    案例 为元素注册点击事件,弹出对话框 <input type="button" id="btn" value="开发分离"> & ...

  4. 出现<authentication mode="Windows"/>错误解决办法

    转自:https://blog.csdn.net/clever101/article/details/39671715 网上下载的asp.net源码出现 <authentication mode ...

  5. Class类文件结构简介

    Java跨平台的基础 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(ByteCode)是构成平台无关性的基石,也是语言无关性的基础.Java虚拟机不和包括Java在内的任何语言绑定 ...

  6. 【SSH网上商城项目实战18】过滤器实现购物登录功能的判断

    转自:https://blog.csdn.net/eson_15/article/details/51425010 上一节我们做完了购物车的基本操作,但是有个问题是:当用户点击结算时,我们应该做一个登 ...

  7. java工厂模式个人体会

    上一边文章主要对单例模式做了一个总结,这篇文章主要对工厂模式也写一写个人的体会. 工厂模式是设计模式的一种,它主要是把实现产品对象的过程封装起来,然后提供给客户端相应的接口.工厂模式也是有3种,分别为 ...

  8. jquery特效:无缝向上循环滚动列表

    效果呈现 整个列表间隔设定的时间向上移动一个item的高度 html结构: <div class="slide-title"> <span>title1&l ...

  9. JDBC基本操作示例

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  10. canvas createPattern()方法详解

    createPattern作用 createPattern() 方法在指定的方向内重复指定的元素. 元素可以是图片.视频,或者其他 <canvas> 元素. 被重复的元素可用于绘制/填充矩 ...