Java的BIO是我们日常开发中经常使用的一组API,然而它的写法是比较繁琐的。像拷贝文件这种简单的功能,也要打开流、关闭流、错误处理等,写上十几行代码才能实现。
commons-io
库对此类操作进行了一些封装,能够简化我们的代码。
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
IOUtils中封装了很多简化流操作的工具方法。
IOUtils.copy
方法能够将数据从输入流拷贝到输出流,省去我们手动编写拷贝的循环逻辑。
public static int copy(@NotNull java.io.InputStream inputStream,
@NotNull java.io.OutputStream outputStream)
throws java.io.IOException
此外还有一个IOUtils.copyLarge
方法,用法和上面相同,只是有更大的缓冲区,适合大量数据拷贝。
public static long copyLarge(@NotNull java.io.InputStream inputStream,
@NotNull java.io.OutputStream outputStream)
throws java.io.IOException
IOUtils.toByteArray
方法能够读取输入流中的全部数据,并存入一个byte[]
类型。该方法能够省去我们编写操作字节数组输出流的代码,非常方便。
public static byte[] toByteArray(@NotNull java.io.InputStream inputStream)
throws java.io.IOException
此外,该方法也有读取字符串的重载方法,但注意需要传入字符编码。
public static String toString(@NotNull java.io.InputStream input,
@Nullable String charsetName)
throws java.io.IOException
和读取输入流类似,IOUtils.write
用于向输出流写数据,包括二进制数据或是字符串。
public static void write(@Nullable byte[] data,
java.io.OutputStream output)
throws java.io.IOException
public static void write(@Nullable String data,
java.io.OutputStream output,
@Nullable String charsetName)
throws java.io.IOException
Java中安全关闭流的写法非常冗长,广受诟病,IOUtils.closeQuietly
方法能够简化这部分操作,支持输入流、输出流等多种参数。
public static void closeQuietly(@Nullable java.io.InputStream input)
public static void closeQuietly(@Nullable java.io.OutputStream output)
如果我们操作的是文件,可以直接使用FileUtils,其中封装了很多简化文件操作的工具方法,包括读取、写入文件,复制、删除、移动文件或文件夹等。
FileUtils.readFileToByteArray
和FileUtils.readFileToString
两个方法能够将文件中的数据读入内存,两个方法分别为二进制字节数组形式和字符串形式。
public static byte[] readFileToByteArray(@NotNull java.io.File file)
throws java.io.IOException
public static String readFileToString(@NotNull java.io.File file,
@Nullable String charsetName)
throws java.io.IOException
FileUtils.writeByteArrayToFile
和FileUtils.write
两个方法能够将二进制字节数组和字符串写入文件。
public static void writeByteArrayToFile(@NotNull java.io.File file,
@NotNull byte[] data)
throws java.io.IOException
public static void write(@NotNull java.io.File file,
@Nullable CharSequence data,
@Nullable String charsetName)
throws java.io.IOException
复制文件是个非常常见的操作,用Java的BIO实现却非常繁琐,FileUtils.copyFile
能够很容易实现该功能。
public static void copyFile(@NotNull java.io.File srcFile,
@NotNull java.io.File destFile)
throws java.io.IOException
除了复制文件,FileUtils.copyDirectory
甚至能实现复制文件夹,这个功能就很强大了,它能够递归复制文件夹和其子目录的所有内容。
public static void copyDirectory(@NotNull java.io.File srcDir,
@NotNull java.io.File destDir)
throws java.io.IOException
注:FileUtils.copyDirectory
还有一个支持过滤器的重载,具体可以参考文档。
FileUtils
支持直接从网络下载文件并保存到磁盘上。
File file = new File("E:/1.png");
FileUtils.copyURLToFile(new URL("https://www.baidu.com/img/flexible/logo/pc/result.png"), file);
commons-io
中还有一个很常用的功能,文件监听。我们可以使用这个功能监听文件的改变、删除等事件,不过要注意的是commons-io
中该功能是使用轮询实现的,这种方式的优点是兼容性好,但文件数很多时性能较差,而且轮询并非实时的,有一些库采用了特定文件系统的回调机制,能够避免这些问题,但兼容性则不好;另外commons-io
必须采用对目录监听的方式,文件夹内的操作都会触发监听器的回调,不支持单个文件的监听。
下面是一个监听e:/dir
文件夹内所有.txt
文件改变的例子。
package com.gacfox.demo;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import java.io.File;
public class Main {
public static void main(String[] args) {
File file = new File("e:/dir");
FileAlterationObserver observer = new FileAlterationObserver(file, pathname -> pathname.getName().endsWith(".txt"));
observer.addListener(new FileAlterationListenerAdaptor() {
@Override
public void onFileChange(File file) {
System.out.println("dir目录中的文件" + file.getName() + "改变了");
}
});
FileAlterationMonitor monitor = new FileAlterationMonitor(1000L);
monitor.addObserver(observer);
try {
monitor.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
代码中,我们首先创建了FileAlterationObserver
并指定它监听e:/dir
文件夹,这里FileAlterationObserver
构造函数中,第二个参数是FileFilter
类型,用于指定一个文件监听的过滤器,我们这里采用Lambda表达式简化了写法。随后我们给FileAlterationObserver
注册FileAlterationListener
,其中覆盖了onFileChange()
方法,目录中的.txt
文件改变时就会触发这个方法内部的逻辑。最后我们创建了FileAlterationMonitor
并将其启动。FileAlterationMonitor
内部会开启新的线程对文件监听和回调。
除了上面提到的几个工具类,commons-io
中还包含许多有用的工具,具体可以参考文档。