关于IO操作Guava给我们提供了很多工具类,大大提高了我们开发效率.下面我们将对Guava IO 提供的相关工具类做一个简单的介绍.涉及到的工具类主要有:ByteStreams,CharStreams,Resources,Closeables,Flushables,Files,MoreFiles.
一 ByteStreams
ByteStreams里面提供用于处理字节数组和I / O流的实用程序方法。
1.1 ByteStreams常用方法
public final class ByteStreams {
/**
* 拷贝从from到to
*/
@CanIgnoreReturnValue
public static long copy(InputStream from, OutputStream to) throws IOException;
/**
* 拷贝从from到to
*/
@CanIgnoreReturnValue
public static long copy(ReadableByteChannel from, WritableByteChannel to) throws IOException;
/**
* InputStream里面的数据读到byte数组里面去
*/
public static byte[] toByteArray(InputStream in) throws IOException;
/**
*
* 从给定的InputStream读取并丢弃数据,直到到达流的末尾。返回读取的总字节数。不关闭流
*/
@CanIgnoreReturnValue
@Beta
public static long exhaust(InputStream in) throws IOException;
/**
* byte数组里面的数据导入到ByteArrayDataInput里面去
*/
@Beta
public static ByteArrayDataInput newDataInput(byte[] bytes);
/**
* byte数组里面的数据导入到ByteArrayDataInput里面去
*/
@Beta
public static ByteArrayDataInput newDataInput(byte[] bytes, int start);
/**
* ByteArrayInputStream里面的数据导入到ByteArrayDataInput里面去
*/
@Beta
public static ByteArrayDataInput newDataInput(ByteArrayInputStream byteArrayInputStream);
/** 返回ByteArrayDataOutput,默认size = 32 */
@Beta
public static ByteArrayDataOutput newDataOutput() {
return newDataOutput(new ByteArrayOutputStream());
}
/**
* 返回ByteArrayDataOutput,给定了初始数组大小size
*/
@Beta
public static ByteArrayDataOutput newDataOutput(int size);
/**
* 返回ByteArrayDataOutput,并且把ByteArrayOutputStream里面的数据导入进去
*/
@Beta
public static ByteArrayDataOutput newDataOutput(ByteArrayOutputStream byteArrayOutputSteam);
/**
* 返回一个空的OutputStream,里面什么数据也没有
*/
@Beta
public static OutputStream nullOutputStream();
/**
* 重新包装下InputStream,限制可读的字节数
*/
@Beta
public static InputStream limit(InputStream in, long limit);
/**
* InputStream里面的数据读到byte数组里面去。如果读到数据的长度和给定的数组长度不相同抛EOFException异常
*/
@Beta
public static void readFully(InputStream in, byte[] b) throws IOException;
/**
* InputStream里面的数据读到byte数组里面去,如果读到数据的长度和给定的len长度不相同抛EOFException异常
*/
@Beta
public static void readFully(InputStream in, byte[] b, int off, int len) throws IOException;
/**
* InputStream里面丢弃n个字节的数据
*/
@Beta
public static void skipFully(InputStream in, long n) throws IOException;
/**
* 把InputStream里面的数据用ByteProcessor来处理
*/
@Beta
@CanIgnoreReturnValue // some processors won't return a useful result
public static <T> T readBytes(InputStream input, ByteProcessor<T> processor);
/**
* 把InputStream里面的数据读到byte数组里面去
*/
@Beta
@CanIgnoreReturnValue
// Sometimes you don't care how many bytes you actually read, I guess.
// (You know that it's either going to read len bytes or stop at EOF.)
public static int read(InputStream in, byte[] b, int off, int len);
}
1.2 ByteStreams简单使用
// ByteStreams.copy()方法,数据拷贝
@Test
public void copy() {
URL url = Resources.getResource("application.yml");
File f = new File(url.getFile()); // 声明File对象
InputStream inputStream = null;
try {
inputStream = new FileInputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (inputStream == null) {
return;
}
try {
OutputStream outputStream = new FileOutputStream("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "abc.txt");
// 把InputStream里面的内容写入到OutputStream里面去
ByteStreams.copy(inputStream, outputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// ByteStreams.toByteArray()方法,把InputStream里面的数据读到数组里面去
@Test
public void toByteArray() {
URL url = Resources.getResource("application.yml");
File f = new File(url.getFile()); // 声明File对象
// InputStream
InputStream inputStream = null;
try {
inputStream = new FileInputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (inputStream == null) {
return;
}
try {
// InputStream里面的内容读到byte数组里面去
byte[] byteArrary = ByteStreams.toByteArray(inputStream);
System.out.println(new String(byteArrary));
} catch (IOException e) {
e.printStackTrace();
}
}
// ByteStreams.read() 把
@Test
public void read() {
URL url = Resources.getResource("application.yml");
File f = new File(url.getFile()); // 声明File对象
// InputStream
InputStream inputStream = null;
try {
inputStream = new FileInputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (inputStream == null) {
return;
}
try {
byte[] byteArray = new byte[1024];
int readLength = ByteStreams.read(inputStream, byteArray, 0, 1024);
System.out.println("读取都的数据长度 = " + readLength);
} catch (IOException e) {
e.printStackTrace();
}
}
二 CharStreams
CharStreams
提供用于处理字符流的实用方法.
2.1 CharStreams常用方法
public final class CharStreams {
/**
* 数据复制
*/
@CanIgnoreReturnValue
public static long copy(Readable from, Appendable to) throws IOException;
/**
* Readable里面的数据转换为String
*/
public static String toString(Readable r) throws IOException;
/**
* Readable里面的数据按行读出来放到List<String>里面去。读文件的时候经常用到
*/
@Beta
public static List<String> readLines(Readable r) throws IOException;
/**
* 一行一行的读数据,一行一行的交给processor去处理
*/
@Beta
@CanIgnoreReturnValue // some processors won't return a useful result
public static <T> T readLines(Readable readable, LineProcessor<T> processor) throws IOException;
/**
* 从给定的Readable读取并丢弃数据,直到到达流的末尾,相当于清空数据
*/
@Beta
@CanIgnoreReturnValue
public static long exhaust(Readable readable) throws IOException;
/**
* 从reader里面丢弃指定的字节
*/
@Beta
public static void skipFully(Reader reader, long n) throws IOException;
/**
* 返回一个空的Writer,里面什么数据也没得
*/
@Beta
public static Writer nullWriter();
/**
* 返回一个Writer,并且把target里面的数据导入进去
*/
@Beta
public static Writer asWriter(Appendable target);
}
2.2 CharStreams简单使用
// CharStreams.copy() 字符流拷贝
@Test
public void copy() {
URL url = Resources.getResource("application.yml");
File f = new File(url.getFile()); // 声明File对象
try {
BufferedReader in = new BufferedReader(new FileReader(f));
StringBuilder stringBuilder = new StringBuilder();
CharStreams.copy(in, stringBuilder);
System.out.println(stringBuilder.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
// CharStreams.readLines() 一行,一行的读取数据
@Test
public void readLines() {
URL url = Resources.getResource("application.yml");
File f = new File(url.getFile()); // 声明File对象
try {
BufferedReader in = new BufferedReader(new FileReader(f));
List<String> lineList = CharStreams.readLines(in);
for (String lineItem : lineList) {
System.out.println(lineItem);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// CharStreams.readLines(),并且交给LineProcessor处理
@Test
public void readLines2() {
URL url = Resources.getResource("application.yml");
File f = new File(url.getFile()); // 声明File对象
try {
BufferedReader in = new BufferedReader(new FileReader(f));
List<String> lineList = CharStreams.readLines(in, new LineProcessor<List<String>>() {
List<String> resultList = Lists.newArrayList();
@Override
public boolean processLine(String line) throws IOException {
resultList.add(line);
return true;
}
@Override
public List<String> getResult() {
return resultList;
}
});
// 打印结果
for (String lineItem : lineList) {
System.out.println(lineItem);
}
} catch (IOException e) {
e.printStackTrace();
}
}
三 Resources
提供用于处理类路径中的资源的实用程序方法。
3.1 Resources常用方法
public final class Resources {
private Resources() {}
/**
* URL对应的数据,读到ByteSource里面
*/
public static ByteSource asByteSource(URL url);
/**
* URL对应的数据,读到CharSource里面
*/
public static CharSource asCharSource(URL url, Charset charset);
/**
* URL对应的数据读到byte数组里面去
*/
public static byte[] toByteArray(URL url) throws IOException;
/**
* URL对应数据读到String里面去
*/
public static String toString(URL url, Charset charset) throws IOException;
/**
* URL对应数据一行一行读,一行一行给callback处理
*/
@CanIgnoreReturnValue // some processors won't return a useful result
public static <T> T readLines(URL url, Charset charset, LineProcessor<T> callback)
throws IOException;
/**
* URL数据一行一行读出来放到List<String>里面去
*/
public static List<String> readLines(URL url, Charset charset) throws IOException;
/**
* URL里面数据拷贝到OutputStream里面去
*/
public static void copy(URL from, OutputStream to) throws IOException;
/**
* 返回resourceName对应的java资源的URL
*/
@CanIgnoreReturnValue // being used to check if a resource exists
// TODO(cgdecker): maybe add a better way to check if a resource exists
// e.g. Optional<URL> tryGetResource or boolean resourceExists
public static URL getResource(String resourceName);
/**
* 同上,contextClass用来指定从contextClass所在路径出发,去查找resourceName对应资源文件
*/
public static URL getResource(Class<?> contextClass, String resourceName);
}
3.2 Resources简单使用
// Resources.getResource()
@Test
public void getResource() {
System.out.println(Resources.getResource("application.yml"));
// 起始路径不一样
System.out.println(Resources.getResource(ResourcesTest.class, "ResourcesTest.class"));
}
// Resources.readLines()
@Test
public void readLines() {
// 我们把application.yml文件的内容读取出来
URL url = Resources.getResource("application.yml");
try {
// Resources.readLines
List<String> lineList = Resources.readLines(url, Charsets.UTF_8);
for (String lineItem : lineList) {
System.out.println(lineItem);
}
// Resources.readLines +
List<String> lineList2 = Resources.readLines(url, Charsets.UTF_8, new LineProcessor<List<String>>() {
List<String> lines = Lists.newArrayList();
@Override
public boolean processLine(String line) throws IOException {
lines.add(line);
return true;
}
@Override
public List<String> getResult() {
return lines;
}
});
for (String lineItem : lineList2) {
System.out.println(lineItem);
}
} catch (IOException e) {
e.printStackTrace();
}
}
四 Closeables
Closeables对象的实用方法。让我们调用一些close方法更加的方便一点.
4.1 Closeables常用方法
public final class Closeables{
/**
* 调用可关闭对象Closeable的close方法.
*
* swallowIOException=true,不会抛出异常,false会抛出异常
*/
public static void close(@Nullable Closeable closeable, boolean swallowIOException)
throws IOException;
/**
* InputStream关闭
*/
public static void closeQuietly(@Nullable InputStream inputStream);
/**
* Reader关闭
*/
public static void closeQuietly(@Nullable Reader reader);
}
五 Flushables
Flushables对象的一些使用方法,让我们调用flush方法更加的方便一点.
Flushables常用方法
public final class Flushables {
/**
* 把可以flush的Flushable对象,调用flush方法
* swallowIOException:true 不会抛出IOException异常,false会抛出IOException异常
*/
public static void flush(Flushable flushable, boolean swallowIOException) throws IOException;
/**
* flush(flushable, true);
*/
public static void flushQuietly(Flushable flushable);
}
六 Files
Files类提供使用文件相关的一些实用程序方法.
6.1 Files常用方法
public final class Files {
/**
* 把文件信息读到BufferedReader里面去
*/
@Beta
public static BufferedReader newReader(File file, Charset charset) throws FileNotFoundException;
/**
* 把文件信息和BufferedWriter关联起来
*/
@Beta
public static BufferedWriter newWriter(File file, Charset charset) throws FileNotFoundException;
/**
* 把文件信息读到ByteSource里面去
*/
public static ByteSource asByteSource(File file);
/**
* 把文件里面的内容以append追加方式(覆盖方式可以省略)读到ByteSink里面去
*/
public static ByteSink asByteSink(File file, FileWriteMode... modes);
/**
* 把文件里面的内容读到CharSource里面去
*/
public static CharSource asCharSource(File file, Charset charset);
/**
* 把文件里面的内容读到CharSink里面去
*/
public static CharSink asCharSink(File file, Charset charset, FileWriteMode... modes);
/**
* 把文件里面的内容读到byte数组里面去
*/
@Beta
public static byte[] toByteArray(File file) throws IOException;
/**
* 把文件里面的内容读到String里面去
*/
@Beta
@Deprecated
public static String toString(File file, Charset charset) throws IOException;
/**
* byte数组里面的内容写到文件里面去
*/
@Beta
public static void write(byte[] from, File to) throws IOException;
/**
* CharSequence内容写到文件里面去
*/
@Beta
@Deprecated
public static void write(CharSequence from, File to, Charset charset) throws IOException;
/**
* 把文件里面的内容拷贝到OutputStream里面去(个人认为和读出来的意思是一样的)
*/
@Beta
public static void copy(File from, OutputStream to) throws IOException;
/**
* 把一个人家的内容拷贝到另一个文件里面去
*/
@Beta
public static void copy(File from, File to) throws IOException;
/**
* 判断两个文件的内容是否相同
*/
@Beta
public static boolean equal(File file1, File file2) throws IOException;
/**
* 创建一个临时文件(由java.io.tmpdir指定的操作系统缓存的临时目录下)
*/
@Beta
public static File createTempDir();
/**
* 创建一个空文件或更新上次更新的时间戳,与同名的unix命令相
*/
@Beta
@SuppressWarnings("GoodTime") // reading system time without TimeSource
public static void touch(File file) throws IOException;
/**
* 必要时为文件创建父目录(文件路径里面有父路径)
*/
@Beta
public static void createParentDirs(File file) throws IOException;
/**
* 把文件从一个路径移动到另一个路径
*/
@Beta
public static void move(File from, File to) throws IOException;
/**
* 读取文件的第一行数据
*/
@Beta
@Deprecated
public
static String readFirstLine(File file, Charset charset) throws IOException;
/**
* 一行,一行的把文件读取出来
*/
@Beta
public static List<String> readLines(File file, Charset charset) throws IOException;
/**
* 一行,一行的把文件读取出来,然后交给LineProcessor去处理
*/
@Beta
@Deprecated
@CanIgnoreReturnValue // some processors won't return a useful result
public
static <T> T readLines(File file, Charset charset, LineProcessor<T> callback) throws IOException;
/**
* 读取文件并且把读出来的内容交给ByteProcessor去处理
*/
@Beta
@Deprecated
@CanIgnoreReturnValue // some processors won't return a useful result
public
static <T> T readBytes(File file, ByteProcessor<T> processor) throws IOException;
/**
* 对文件做hash操作
*/
@Beta
@Deprecated
public
static HashCode hash(File file, HashFunction hashFunction) throws IOException;
/**
* 把文件的内容读到MappedByteBuffer里面去
* java nio中引入了一种基于MappedByteBuffer操作大文件的方式,其读写性能极高
*/
@Beta
public static MappedByteBuffer map(File file) throws IOException;
/**
* 把文件的内容读到MappedByteBuffer里面去
*/
@Beta
public static MappedByteBuffer map(File file, MapMode mode) throws IOException;
/**
* 把文件的内容读到MappedByteBuffer里面去
*/
@Beta
public static MappedByteBuffer map(File file, MapMode mode, long size) throws IOException;
/**
* 规范文件路径,并不总是与文件系统一致,请仔细测试
*/
@Beta
public static String simplifyPath(String pathname);
/**
* 返回给定路径所表示文件的扩展名
*/
@Beta
public static String getFileExtension(String fullName);
/**
* 返回去除了扩展名的文件名
*/
@Beta
public static String getNameWithoutExtension(String file);
/**
* 返回文件和目录树的raverser实例。返回的遍历器从File开始,将返回它遇到的所有文件和目录。
*/
@Beta
public static Traverser<File> fileTraverser() {
return Traverser.forTree(FILE_TREE);
}
/**
* 返回一个Predicate对象,用于判断文件是否是目录文件
*/
@Beta
public static Predicate<File> isDirectory();
/**
* 返回一个Predicate,用于判断是否是文件
*/
@Beta
public static Predicate<File> isFile();
}
6.2 Files简单使用
// Files.newReader() 把文件的内容读到BufferedReader里面去
@Test
public void newReader() {
// 这里,需要换成你电脑存在的地址
File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "application.yml");
try {
BufferedReader bufferedReader = Files.newReader(file, Charsets.UTF_8);
List<String> lineList = CharStreams.readLines(bufferedReader);
for (String lineItem : lineList) {
System.out.println(lineItem);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Files.newWriter
@Test
public void newWriter() {
File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "filewirite.txt");
try {
BufferedWriter bufferedWriter = Files.newWriter(file, Charsets.UTF_8);
bufferedWriter.write("hello word!!!");
// bufferedWriter.flush();
Flushables.flushQuietly(bufferedWriter);
} catch (IOException e) {
e.printStackTrace();
}
}
// Files.asByteSink
@Test
public void asByteSink() {
File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "filewirite.txt");
try {
ByteSink byteSink = Files.asByteSink(file, FileWriteMode.APPEND);
OutputStream outputStream = byteSink.openStream();
outputStream.write("hello word!!!".getBytes(Charsets.UTF_8));
// bufferedWriter.flush();
Flushables.flushQuietly(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 对文件做hash操作
@Test
public void hash() {
File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "filewirite.txt");
try {
HashCode hashCode = Files.asByteSource(file).hash(Hashing.sha256());
System.out.println(hashCode.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
// Files.fileTraverser() 用于遍历文件
@Test
public void fileTraverser() {
Traverser<File> traverser = Files.fileTraverser();
File file = new File("/home/tuacy/github/google-guava-study/src/main/resources");
Iterable<File> list = traverser.breadthFirst(file);
list.forEach(new Consumer<File>() {
@Override
public void accept(File file) {
System.out.println(file.getName());
}
});
}
七 MoreFiles
MoreFiles类是Files类的一个补充类,MoreFiles里面的方法也是操作文件相关的方法,不过MoreFiles针对的是Path类,关于Path类和File的的区别和用法可以自己去百度下,两者都是操作文件的对象.
7.1 MoreFiles常用方法
public final class MoreFiles {
/**
* 文件内容读到ByteSource里面去
*/
public static ByteSource asByteSource(Path path, OpenOption... options);
/**
* 文件内容关联ByteSink,这样可以通过ByteSink把内容写到文件里面去
*/
public static ByteSink asByteSink(Path path, OpenOption... options);
/**
* 文件内容读到CharSource里面去u
*/
public static CharSource asCharSource(Path path, Charset charset, OpenOption... options);
/**
* 文件关联CharSink,这样可以通过CharSink把内容写到文件里面去
*/
public static CharSink asCharSink(Path path, Charset charset, OpenOption... options);
/**
* 获取指定目录下的文件
*/
public static ImmutableList<Path> listFiles(Path dir) throws IOException;
/**
* 返回Traverser,用于遍历文件
*/
public static Traverser<Path> fileTraverser();
/**
* 返回一个表示目录文件的Predicate,
*/
public static Predicate<Path> isDirectory(LinkOption... options);
/**
* 返回Predicate,用于判断文件是不是一个正常的文件
*/
public static Predicate<Path> isRegularFile(LinkOption... options);
/**
* 两个path对应的文件内容是否相同
*/
public static boolean equal(Path path1, Path path2) throws IOException;
/**
* 创建一个空文件或更新上次更新的时间戳
*/
@SuppressWarnings("GoodTime") // reading system time without TimeSource
public static void touch(Path path) throws IOException;
/**
* 创建父目录
*/
public static void createParentDirectories(Path path, FileAttribute<?>... attrs)
throws IOException;
/**
* 返回给定路径所表示文件的扩展名
*/
public static String getFileExtension(Path path);
/**
* 返回去除了扩展名的文件名
*/
public static String getNameWithoutExtension(Path path);
/**
* 删除整个目录
*/
public static void deleteRecursively(Path path, RecursiveDeleteOption... options)
throws IOException;
/**
* 删除目录下面的文件
*/
public static void deleteDirectoryContents(Path path, RecursiveDeleteOption... options)
throws IOException;
}
7.2 MoreFiles简单使用
// MoreFiles.asCharSource()
@Test
public void asCharSource() {
Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources/abc.txt");
CharSource charSource = MoreFiles.asCharSource(path, Charsets.UTF_8);
try {
BufferedReader bufferedReader = charSource.openBufferedStream();
List<String> lines = CharStreams.readLines(bufferedReader);
for (String lineItem : lines) {
System.out.println(lineItem);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// MoreFiles.deleteDirectoryContents() 删除目录里面的文件
// MoreFiles.deleteRecursively() 删除目录已经目录里面的文件
@Test
public void deleteDirectoryContents() {
Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources/abc");
try {
MoreFiles.deleteDirectoryContents(path, RecursiveDeleteOption.ALLOW_INSECURE);
MoreFiles.deleteDirectoryContents(path, RecursiveDeleteOption.ALLOW_INSECURE);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void createParentDirectories() {
Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources/abc/123/789/abc.txt");
try {
MoreFiles.createParentDirectories(path);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void isDirectory() {
Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources");
Predicate<Path> predicate = MoreFiles.isDirectory();
System.out.println("是否目录 = " + predicate.apply(path));
}
关于Guava I/O 部分的内容,我们就先讲这些主要是一些工具类的使用,熟悉ByteStreams,CharStreams,Resources,Closeables,Flushables,Files,MoreFiles这些个工具类里面方法的使用. 充分的把他们用到我们实际开发当中去.相关实例代码可以在 https://github.com/tuacy/google-guava-study 测试包下com.tuacy.guava.study.io包里面找到.