博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Guava包学习---I/O
阅读量:5901 次
发布时间:2019-06-19

本文共 9014 字,大约阅读时间需要 30 分钟。

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
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
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
>() { final List
result = Lists.newArrayList(); @Override public boolean processLine(String line) { result.add(line); return true; } @Override public List
getResult() { return result; } }); }

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

public static 
T readLines(File file, Charset charset, LineProcessor
callback) throws IOException { return asCharSource(file, charset).readLines(callback); }
public static 
T readBytes(File file, ByteProcessor
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
components = Splitter.on('/').omitEmptyStrings().split(pathname); List
path = new ArrayList
(); // 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; }

 

转载于:https://www.cnblogs.com/congsg2016/p/5128730.html

你可能感兴趣的文章
sshtunnel在本地访问云服务器mysql
查看>>
Java类加载器( 死磕8)
查看>>
小蚂蚁学习APP接口开发(1)—— json方式封装通信接口
查看>>
我的友情链接
查看>>
CDN相关
查看>>
Tomcat的设置4——Tomcat的体系结构与设置基于端口号的虚拟主机
查看>>
三种判断端口存活的方法和链接200的判断方法
查看>>
我的友情链接
查看>>
ftp协议基础
查看>>
顺时针打印矩阵
查看>>
JAXB
查看>>
端口聚合配置
查看>>
访问共享经常中断
查看>>
当你有一个锤子,你看什么都像钉子
查看>>
一个很实用的samba案例
查看>>
100个MySQL的调节和优化的提示
查看>>
HostMonster主机修改文件权限的方法
查看>>
人生的交易
查看>>
TP5中关联模型的使用详解
查看>>
springMVC注解之入门
查看>>