Guava包学习---I/O
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的更多相关文章
- Guava包学习---Lists
Guava包是我最近项目中同事推荐使用的,是google推出的库.里面的功能非常多,包括了集合.缓存.原生类型支持.并发库.通用注解.字符串处理.IO等.我们项目中使用到了guava依赖,但是实际上只 ...
- Guava包学习--EventBus
之前没用过这个EventBus,然后看了一下EventBus的源码也没看明白,(-__-)b.反正大概就是弄一个优雅的方式实现了观察者模式吧.慢慢深入学习一下. 观察者模式其实就是生产者消费者的一个变 ...
- Guava包学习-Cache
这段时间用到了ehcache和memcache,memcache只用来配置在tomcat中做负载均衡过程中的session共享,然后ehcache用来存放需要的程序中缓存. Guava中的Cache和 ...
- Guava包学习---Maps
Maps包方法列表: 还是泛型创建Map: public static <K, V> HashMap<K, V> newHashMap() { return new HashM ...
- Guava包学习--Hash
我们HashMap会有一个rehash的过程,为什么呢?因为java内建的散列码被限制为32位,而且没有分离散列算法和所作用的数据,所以替代算法比较难做.我们使用HashMap的时候它自身有一个reh ...
- Guava包学习---Bimap
Bimap也是Guava中提供的新集合类,别名叫做双向map,就是key->value,value->key,也就是你可以通过key定位value,也可以用value定位key. 这个场景 ...
- Guava包学习-Multimap
它和上一章的MultiSet的继承结果很相似,只不过在上层的接口是Multimap不是Multiset. Multimap的特点其实就是可以包含有几个重复Key的value,你可以put进入多个不同v ...
- Guava包学习---Sets
Sets包的内容和上一篇中的Lists没有什么大的区别,里面有些细节可以看一下: 开始的创建newHashSet()的各个重载方法.newConcurrentHashSet()的重载方法.newTre ...
- Guava包学习--Table
Table,顾名思义,就好像HTML中的Table元素一样,其实就是行+列去确定的值,更准确的比喻其实就是一个二维矩阵. 其实它就是通过行+列两个key去找到一个value,然后它又containsv ...
随机推荐
- golang数组与切片
golang中坑的慢慢踩! golang中的数组是值类型,函数调用是传入的是数组的拷贝,如果想改变数组的值,可考虑使用指针数组,即函数调用时传入数组的地址 golang中的切片是引用类型,但是在函数中 ...
- SpringBoot 之Quartz的使用
对于Quartz的使用,还是想说一句,SpringBoot真的很好用啊! 第一步:当然是引入依赖啦 <parent> <groupId>org.springframework. ...
- 中南月赛F ZZY and his little friends
Problem F: ZZY and his little friends Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 137 Solved: 70 ...
- PHP-redis英文文档
作为程序员,看英文文档是必备技能,所以尽量还是多看英文版的^^ PhpRedis The phpredis extension provides an API for communicating wi ...
- mysql数据导入mongoDB
目前许多平台都会同时使用MySQL , mongoDB 两款数据库软件,他们之间的数据同步交换也是经常面临的问题,如何定时的进行数据交换同步是一个要面对的问题. 通过Treesoft数据库管理系统可以 ...
- MIME格式说明,电子邮件格式(转载)
邮件格式说明 Mutiple Internet Mail Extensions Refer to Internet Official Protocol Standards RFC 822 1 概述 网 ...
- 第二天-while循环 格式化输出 运算符 编码
一.while循环 while 条件: 语句块(循环体) #判断条件是否成立,若成立执行循环体,然后再次判断条件...直到不满足跳出循环 else: 当条件不成立的时候执行这里,和break没 ...
- 虚树(Bzoj3611: [Heoi2014]大工程)
题面 传送门 虚树 把跟询问有关的点拿出来建树,为了方便树\(DP\) 在\(LCA\)处要合并答案,那么把这些点的\(LCA\)也拿出来 做法:把点按\(dfs\)序排列,然后求出相邻两个点的\(L ...
- drupal 通过hook_menu实现添加菜单
$items['mypayment/onlinepay']=array( 'title' => '在线充值', 'description' => '在线充值', 'page callbac ...
- 30分钟掌握ES6/ES2015核心内容[上和下], 不错的说
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...