【Guava】IO工具
引言
Guava 使用术语 流来表示可关闭的,并且在底层资源中有位置状态的 I/O 数据流。字节流对应的工具类为 ByteSterams,字符流对应的工具类为 CharStreams。
Guava 中为了避免和流直接打交道,抽象出可读的 源 source 和可写的 汇 sink 两个概念,指可以从中打开流的资源,比如 File、URL,同样也分别有字节和字符对应的源和汇,定义了一系列读写的方法。
Guava IO 极大简化了文件和流的操作。比如说,读写文件这种看似简单的操作,在Java原生代码中可能要写好几行,还不包括错误处理。Guava则可以用一两行搞定,简洁到让人惊叹。其次,它还提供了更丰富的功能,比如对不同字符集的处理,还有资源的高效管理。这些都是在开发过程中经常遇到的问题,Guava给了我们优雅的解决方案。
来看个简单的例子,比如说读取一个文本文件的内容。在Java原生代码中,可能得这么写:
try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
但是用Guava,就可以变得超级简单:
List<String> lines = Files.asCharSource(new File("example.txt"), Charsets.UTF_8).readLines();
lines.forEach(System.out::println);
看到区别了吧?Guava的代码不仅更短,而且可读性也强很多。而且,Guava还考虑了很多细节,比如字符集处理,在这里用的是Charsets.UTF_8,这在处理有不同编码的文件时特别有用。
文件操作简化
在Java的世界里,文件操作是个老生常谈的话题。传统的Java I/O操作,虽然功能强大,但代码写起来往往既长又复杂,但是,有了Guava,这一切都变得轻松多了。
读取文件
读取文件场景中,在Java原生方法里,可能需要创建FileReader,然后再包装成BufferedReader,最后一行一行地读。但在Guava中,只需要几行代码,就能搞定。
看这个例子:
// 使用Guava读取文件
File file = new File("example.txt");
List<String> lines = Files.asCharSource(file, Charsets.UTF_8).readLines();
for (String line : lines) {
System.out.println(line);
}

在这段代码里,Files.asCharSource方法创建了一个字符源(CharSource),这样就可以直接读取文件中的内容了。再也不用担心FileNotFoundException和IOException这些让人头疼的异常了,Guava都处理好了一切。
写入文件
在传统的Java I/O中,写文件也是一大堆代码,需要处理流的打开和关闭,还得小心处理异常。但在Guava中,这也变得超级简单:
// 使用Guava写入文件
List<String> content = Arrays.asList("Line 1", "Line 2", "Line 3");
File file = new File("example-write.txt");
Files.asCharSink(file, Charsets.UTF_8).writeLines(content);

在这里,Files.asCharSink创建了一个字符汇(CharSink),它能轻松写入数据到文件中。这些代码不仅简洁,而且易于理解和维护。
复制和移动文件
但Guava的魔法不止于此。想要复制或者移动文件?也是分分钟的事情。看看这个:
// 复制文件
File original = new File("source.txt");
File copy = new File("destination.txt");
Files.copy(original, copy);
// 移动文件
File toMove = new File("toMove.txt");
File destination = new File("moved.txt");
Files.move(toMove, destination);
流处理与转换
在Java中,流(Streams)是处理数据的核心,不论是文件I/O还是网络通信,流都扮演着至关重要的角色。但有时候,处理Java原生的InputStream和OutputStream会让人觉得有点小复杂。幸好,Guava在这方面提供了非常便捷的工具,让流处理变得既简单又高效。
简化的流读取
在传统的Java I/O中,从InputStream读取数据通常需要创建一个buffer,然后一点点读取。但用Guava,整个过程就变得异常简单:
// 使用Guava从InputStream读取字符串
InputStream input = new FileInputStream("example.txt");
String text = CharStreams.toString(new InputStreamReader(input, Charsets.UTF_8));
input.close();
在这里,CharStreams.toString方法直接将整个InputStream转换为字符串。再也不需要手动创建buffer和循环读取了,一行代码就搞定。
流的转换和处理
有时候,需要对流中的数据进行某种形式的处理或转换。Guava在这方面也提供了很大的帮助。看看这个例子:
// 使用Guava对InputStream进行转换
InputStream input = new FileInputStream("example.txt");
FluentIterable<String> lines =
CharStreams.readLines(new InputStreamReader(input, Charsets.UTF_8))
.transform(line -> line.toUpperCase()); // 将每一行都转换为大写
input.close();
在这个例子中,CharStreams.readLines方法读取了所有行,并且通过transform方法对每一行进行了转换,这里是将其转换为大写。Guava的流式处理风格让这种转换变得非常优雅。
高效的流拷贝
在Java中,从一个流拷贝数据到另一个流通常需要手动创建buffer,并循环进行读写。但在Guava中,这也变得简单多了:
// 使用Guava进行流拷贝
InputStream input = new FileInputStream("source.txt");
OutputStream output = new FileOutputStream("dest.txt");
ByteStreams.copy(input, output); // 将数据从input流拷贝到output流
input.close();
output.close();
在这个例子中,ByteStreams.copy方法就直接完成了从一个流到另一个流的数据拷贝。Guava把复杂的操作隐藏在了简洁的API背后,大大降低了编码的复杂性。
字符集与编码处理
在Java世界里,字符集和编码经常会让人头疼,特别是当处理不同来源的数据时,比如从不同的文件或网络。字符编码问题能让一个简单的任务变得异常复杂。但别担心,Guava来帮忙了!
字符编码的挑战
在Java中,处理不同编码的文本,尤其是在I/O操作中,经常会遇到UnsupportedEncodingException。这是因为不同的系统和文本文件可能使用不同的字符编码。比如,Windows可能默认使用CP1252,而Linux可能使用UTF-8。如果不正确处理这些编码,就会导致乱码或者错误。
Guava的Charsets
Guava提供了一套字符集(Charsets)工具,让处理这些问题变得简单。Guava定义了所有标准的Java字符集,这样咱们就不必手动处理那些繁琐的字符串了。比如,当需要转换字节数据到字符串,或者相反的操作时,Guava的Charsets就派上用场了。
看看下面这个例子:
// 使用Guava的Charsets处理字符串
String example = "这是一个测试字符串";
byte[] bytes = example.getBytes(Charsets.UTF_8); // 将字符串转换为UTF-8编码的字节
String decoded = new String(bytes, Charsets.UTF_8); // 再将字节解码回字符串
System.out.println(decoded);
在这段代码里,使用Charsets.UTF_8来确保字符串正确地被编码和解码。Guava的Charsets处理起来既简单又不易出错。
更多字符处理工具
除了Charsets,Guava还提供了更多字符处理工具。比如,有时咱们需要对字符串中的特定字符进行操作,Guava的CharMatcher类就是专门为此设计的。
来看个例子,假设咱们要从字符串中移除所有数字:
// 使用Guava的CharMatcher移除字符串中的数字
String input = "abc123xyz456";
String result = CharMatcher.inRange('0', '9').removeFrom(input);
System.out.println(result); // 输出结果: "abcxyz"
在这个例子中,CharMatcher.inRange('0', '9')创建了一个匹配所有数字的匹配器,然后removeFrom方法就将这些数字从字符串中移除了。这样的处理不仅代码量少,而且逻辑清晰易懂。
详情可以看这篇文章 String&Ints
源(Source)和汇(Sink)模式
在处理文件和流的时候,常常需要读数据(Source)和写数据(Sink)。Guava在这方面提供了一套非常优雅的解决方案,让这些操作变得既简单又直观。
在Guava中,Source代表一个数据的来源,可以是文件、URL或者任何其他数据源。而Sink则是数据的目的地,比如文件或者某个输出流。这种抽象的好处是,无论数据来源或去向如何变化,操作逻辑都保持一致。
文件的Source和Sink
先来看看文件操作。在传统的Java I/O中,需要创建FileInputStream或FileOutputStream,然后进行读写操作。但用Guava的Source和Sink,整个过程变得更加清晰。
看这个读文件的例子:
// 使用Guava的FileSource读取文件
File file = new File("example.txt");
CharSource charSource = Files.asCharSource(file, Charsets.UTF_8);
String content = charSource.read();
System.out.println(content);
在这段代码中,Files.asCharSource创建了一个CharSource实例,它代表了文件中的字符数据。charSource.read()方法就能读取整个文件的内容。这样的代码不仅简洁,而且非常容易理解。
再来看看写文件的操作:
// 使用Guava的FileSink写入文件
List<String> lines = Arrays.asList("第一行", "第二行", "第三行");
File file = new File("example-write.txt");
CharSink charSink = Files.asCharSink(file, Charsets.UTF_8);
charSink.writeLines(lines);
这里Files.asCharSink创建了一个CharSink实例,它代表文件的写入点。charSink.writeLines方法可以轻松地将一个字符串列表写入文件。
URL的Source
除了文件,Source和Sink还可以用于其他类型的数据源。比如,可以从一个URL读取数据:
// 使用Guava的URLSource读取数据
URL url = new URL("http://example.com");
ByteSource byteSource = Resources.asByteSource(url);
byte[] data = byteSource.read();
System.out.println(new String(data, Charsets.UTF_8));
在这个例子中,Resources.asByteSource创建了一个表示URL数据的ByteSource。然后就可以使用byteSource.read()来读取数据,非常方便。
异常处理与资源管理
在Java编程中,正确处理异常和资源是非常重要的,尤其是在进行I/O操作或者处理外部资源时。如果处理不当,很容易造成资源泄露或程序崩溃。Guava在这方面提供了一些非常棒的工具,帮助咱们写出更安全、更可靠的代码。
快速失败:Preconditions
在开始处理数据之前,检查输入是非常重要的。Guava提供了Preconditions类,帮助咱们快速校验条件,并在条件不满足时立即失败。这种“快速失败”机制有助于尽早发现问题,避免更深层次的错误。
看看这个例子:
// 使用Guava的Preconditions进行参数校验
public void processData(String data) {
Preconditions.checkNotNull(data, "data不能为null");
// 处理数据
}
这段代码中,Preconditions.checkNotNull方法确保传入的data不是null。如果是null,它会抛出一个NullPointerException,并附带自定义的错误消息。这样的校验既直观又有效,有助于提高代码的健壮性。
详情可以看这篇文章 String&Ints
资源管理:Closeables和FluentIterable
在Java中,正确管理资源,特别是那些需要关闭的资源,如流或连接,是非常重要的。Guava的Closeables类提供了便捷的方法来关闭这些资源,而不必担心IOException。
// 使用Guava的Closeables安全关闭资源
InputStream in = null;
try {
in = new FileInputStream("example.txt");
// 使用流
} catch (IOException e) {
// 异常处理
} finally {
Closeables.closeQuietly(in); // 安静地关闭流,忽略IOException
}
在这个例子中,无论在使用流的过程中是否发生异常,Closeables.closeQuietly都会在finally块中安全地关闭流。这样的处理方式不仅简洁,而且可以避免因忘记关闭资源而导致的问题。
Guava的FluentIterable也是资源管理的好帮手。它提供了一种链式的方法来处理集合,使得操作集合变得既简洁又优雅。
// 使用Guava的FluentIterable优雅地处理集合
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> filtered = FluentIterable.from(names)
.filter(name -> name.startsWith("A"))
.toList();
在这段代码中,FluentIterable.from创建了一个可迭代的集合视图,filter方法用于过滤,最后toList将结果转换为List。这样的链式调用,不仅代码可读性高,而且易于维护。
Guava与Java NIO的结合
本章我们要聊聊Guava和Java NIO(非阻塞I/O)的结合。对于那些需要处理大量数据,或者对性能要求较高的应用来说,Java的NIO库是个非常强大的工具。但是,NIO的API有时候会显得有点复杂。这时候,Guava又一次展示了它的魔力,帮助我们更简单、更优雅地使用NIO。
Guava对NIO的增强
Guava对Java NIO做了一些增强,让它的使用变得更加友好。Guava提供了类似于ByteSource和ByteSink这样的抽象,使得使用NIO进行文件操作或网络操作更加直观。
来看看这个读取文件内容的例子:
// 使用Guava的ByteSource读取文件内容
File file = new File("example.txt");
ByteSource byteSource = Files.asByteSource(file);
byte[] readBytes = byteSource.read();
System.out.println(new String(readBytes, Charsets.UTF_8));
在这个例子中,Files.asByteSource方法创建了一个ByteSource实例,它代表文件中的字节数据。然后,可以使用byteSource.read()方法读取这些数据。这种方式比直接使用Java NIO的Channel和Buffer要简单得多。
NIO与流的转换
另一个强大的功能是Guava提供的NIO和流之间的转换。在某些情况下,可能需要在NIO的Channel和Java的InputStream/OutputStream之间进行转换。Guava在这方面提供了便利的工具。
// 使用Guava将InputStream转换为ReadableByteChannel
InputStream inputStream = new FileInputStream("example.txt");
ReadableByteChannel channel = Channels.newChannel(inputStream);
// 使用channel进行操作
在这个例子中,Channels.newChannel方法将一个InputStream转换为一个ReadableByteChannel。这样的转换让我们能够在需要使用NIO时,更加灵活地处理流。
往期推荐
- 《SpringBoot》EasyExcel实现百万数据的导入导出
- 《SpringBoot》史上最全SpringBoot相关注解介绍
- Spring框架IoC核心详解
- 万字长文带你窥探Spring中所有的扩展点
- 如何实现一个通用的接口限流、防重、防抖机制
- 万字长文带你深入Redis底层数据结构
- volatile关键字最全原理剖析
【Guava】IO工具的更多相关文章
- Guava 开源工具的简单介绍
Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libra ...
- java代码之美(8)---guava字符串工具
guava字符串工具 在java开发过程中对字符串的处理是非常频繁的,google的guava工具对字符串的一些处理进行优化,使我们开发过程中让自己的代码看去更加美观,清爽. 一.Joiner 根据给 ...
- Guava集合工具
JDK提供了一系列集合类,如下所示,极大的方便了开发工作,并针对这些类提供了一个工具类java.util.Collections,Guava在此基础上添加了一些常用工具类方法,相比于java.util ...
- java代码(8) ---guava字符串工具
guava字符串工具 一.Joiner 根据指定的分隔符把字符串连接在一起,MapJoiner执行相同的操作,但是针对Map的key和value 分析源码可知:该类构造方法被private修饰,无法直 ...
- google guava 基本工具
近期在项目中用到了google中的cache了解到guava里面的一些工具类和对集合的操作,封装的都比较下,没有时间自己去写,先做个标记, 参考文章如下: http://macrochen.iteye ...
- Linux IO工具 iotop备择方案iopp
iotop毫无疑问linux IO检测上是一个很好的工具,但苦于要求和内核版本Python版本号.我的很多朋友放弃了.我也是.无意中发现iopp,使用c书面,与此iotop它是一个作用.nice! 一 ...
- Guava Preconditions 工具参数前置校验
guava 提供 Preconditions 作为代码校验的工具类,用来简化开发中对代码的校验或预处理,在逻辑开始前进行合理性校验,避免参数传入过深导致的数据错误. 并且能够在不符合校验条件的地方, ...
- Linux下查看进程IO工具iopp
Linux下的IO检测工具最常用的是iostat,不过iostat只能查看到总的IO情况.如果要细看具体那一个程序点用的IO较高,可以使用iotop .不过iotop对内核版本和Python版本有要求 ...
- Guava 常用工具类
引入guava包: <dependency> <groupId>com.google.guava</groupId> <artifactId>guava ...
- 0318 guava并发工具
并发是一个难题,但是可以通过使用强力简单的抽象来显著的简化,为了简化问题,guava扩展了Future接口,即 ListenableFuture (可以监听的Future).我强烈建议你在你的所有代码 ...
随机推荐
- 面向对象(下)的阶段性复习:关键字abstract、模板方法的设计模式、关键字interface、代理模式、工厂的设计模式、类的结构内部类
关键字:abstract abstract: 抽象的1.可以用来修饰:类.方法2.具体的:abstract修饰类:抽象类 * > 此类不能实例化 * > 抽象类中一定有构造器,便于子类实例 ...
- hackmyvm靶机拯救者模式解决分配不到ip的问题 转载
https://www.cnblogs.com/jason-huawen/p/16851113.html https://www.cnblogs.com/asstart/p/12626494.html ...
- HTTPS 证书自动化运维:基础知识与重要性
简介: 随着互联网的飞速发展和网络安全威胁的日益增多,HTTPS(HyperText Transfer Protocol Secure)已经成为保护网站和用户数据安全的标准协议.HTTPS 证书的管理 ...
- 使用 SOUI 开发高 DPI 桌面应用程序[转载]
原文:使用 SOUI 开发高 DPI 桌面应用程序_吹泡泡的小猫的博客-CSDN博客 补充说明:soui3以后版本对dpi的支持更完善了,用起来也更简单了. 1 应用程序感知 DPI 变化 在 Win ...
- shell 条件语句基础练习
#输出1到15数字 #!/bin/bash for i in `seq 1 15` do echo -e "\033[32m$i\033[0m" done #计算1到100数字之和 ...
- Atcoder ABC390E Vitamin Balance 题解 [ 绿 ] [ 背包 ] [ 二分 ]
Vitamin Balance:比较板的背包. 思路 一个 dp 数组里同时存三种食物的最大维他命显然不可行,因为一种食物维他命最多不代表其他维他命也同样多,而最终的价值取决于维他命最少的那个,所以这 ...
- 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-12- iframe操作-上篇(详细教程)
1.简介 原估计宏哥这里就不对iframe这个知识点做介绍和讲解了,因为前边的窗口切换就为这种网页处理提供了思路,另一个原因就是虽然iframe很强大,但是现在很少有网站用它了.但是还是有小伙伴或者童 ...
- 牛客题解 | 单组_spj判断数组之和
题目 题目链接 解题思路 后台有spj代码,能对同学们的输出数据进行校验,符合条件即可通过. 附赠 spj 代码 #include <iostream> #include <fstr ...
- 小米字体和思源宋体CSS调用使用指南
小米字体 //css引用 <link rel="stylesheet" href="https://font.sec.miui.com/font/css?famil ...
- Lobe Chat 数据库版安装和使用教程
DeepSeek 爆火之后官方网站一直繁忙,不少开发者都开始自己动手部署聊天客户端了. 市面上可供选择的套壳 UI 很多,但是论颜值和功能,还得是 Lobe Chat. Lobe Chat 是什么? ...