Contents

Apache Commons IO 简介

1.概述

创建 Apache Commons 项目的目的是为开发人员提供一组可以在日常代码中使用的通用库。

在本教程中,我们将探索 Commons IO 模块的一些关键实用程序类及其最著名的功能。

2. Maven依赖

要使用该库,让我们在pom.xml中包含以下 Maven 依赖项:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

该库的最新版本可以在Maven Central 中找到。

3. 实用程序类

简单地说,实用程序类提供了一组静态方法,可用于对文件执行常见任务

3.1. FileUtils

该类提供了对文件的不同操作,例如打开、读取、复制和移动。

让我们看看如何使用FileUtils读取或复制文件:

File file = FileUtils.getFile(getClass().getClassLoader()
  .getResource("fileTest.txt")
  .getPath());
File tempDir = FileUtils.getTempDirectory();
FileUtils.copyFileToDirectory(file, tempDir);
File newTempFile = FileUtils.getFile(tempDir, file.getName());
String data = FileUtils.readFileToString(newTempFile,
  Charset.defaultCharset());

3.2. FilenameUtils

此实用程序提供了一种与操作系统无关的方法来对文件名执行常用功能。让我们看看我们可以使用的一些不同的方法:

String fullPath = FilenameUtils.getFullPath(path);
String extension = FilenameUtils.getExtension(path);
String baseName = FilenameUtils.getBaseName(path);

3.3. FileSystemUtils

我们可以使用FileSystemUtils检查给定卷或驱动器上的可用空间

long freeSpace = FileSystemUtils.freeSpaceKb("/");

4. 输入输出

这个包提供了几种处理输入和输出流的实现。

我们将专注于TeeInputStreamTeeOutputSteam。单词“ Tee ”(源自字母“ T ”)通常用于描述将单个输入拆分为两个不同的输出。

让我们看一个示例,该示例演示了如何将单个输入流写入两个不同的输出流

String str = "Hello World.";
ByteArrayInputStream inputStream = new ByteArrayInputStream(str.getBytes());
ByteArrayOutputStream outputStream1 = new ByteArrayOutputStream();
ByteArrayOutputStream outputStream2 = new ByteArrayOutputStream();
FilterOutputStream teeOutputStream
  = new TeeOutputStream(outputStream1, outputStream2);
new TeeInputStream(inputStream, teeOutputStream, true)
  .read(new byte[str.length()]);
assertEquals(str, String.valueOf(outputStream1));
assertEquals(str, String.valueOf(outputStream2));

5. 过滤器

Commons IO 包含一个有用的文件过滤器列表。当开发人员想要从异构文件列表中缩小到特定的所需文件列表时,这些可以派上用场。

该库还支持对给定文件列表的ANDOR逻辑运算。因此,我们可以混合和匹配这些过滤器以获得所需的结果。

让我们看一个使用WildcardFileFilterSuffixFileFilter检索名称中带有“ ple ”且后缀为“ txt ”的文件的示例。请注意,我们使用ANDFileFilter包装上述过滤器:

@Test
public void whenGetFilewith_ANDFileFilter_thenFind_sample_txt()
  throws IOException {
    String path = getClass().getClassLoader()
      .getResource("fileTest.txt")
      .getPath();
    File dir = FileUtils.getFile(FilenameUtils.getFullPath(path));
    assertEquals("sample.txt",
      dir.list(new AndFileFilter(
        new WildcardFileFilter("*ple*", IOCase.INSENSITIVE),
        new SuffixFileFilter("txt")))[0]);
}

6. 比较器

Comparator包提供了不同类型的文件比较。我们将在这里探讨两种不同的比较器。

6.1. PathFileComparator

PathFileComparator类可用于以区分大小写、不区分大小写或系统相关的区分大小写的方式**按路径对文件列表或数组进行排序。**让我们看看如何使用此实用程序对资源目录中的文件路径进行排序:

@Test
public void whenSortDirWithPathFileComparator_thenFirstFile_aaatxt() 
  throws IOException {
    
    PathFileComparator pathFileComparator = new PathFileComparator(
      IOCase.INSENSITIVE);
    String path = FilenameUtils.getFullPath(getClass()
      .getClassLoader()
      .getResource("fileTest.txt")
      .getPath());
    File dir = new File(path);
    File[] files = dir.listFiles();
    pathFileComparator.sort(files);
    assertEquals("aaa.txt", files[0].getName());
}

请注意,我们使用了IOCase.INSENSITIVE配置。PathFileComparator还提供了许多具有不同区分大小写和反向排序选项的单例实例

这些静态字段包括PATH_COMPARATOR、PATH_INSENSITIVE_COMPARATOR、PATH_INSENSITIVE_REVERSE、PATH_SYSTEM_COMPARATOR等等。

6.2. SizeFileComparator

SizeFileComparator,顾名思义,是用来比较两个文件的大小(长度)的。如果第一个文件的大小小于第二个文件的大小,则返回一个负整数值。如果文件大小相等,则返回零,如果第一个文件的大小大于第二个文件的大小,则返回正值。

让我们编写一个单元测试来演示文件大小的比较:

@Test
public void whenSizeFileComparator_thenLargerFile_large()
  throws IOException {
    SizeFileComparator sizeFileComparator = new SizeFileComparator();
    File largerFile = FileUtils.getFile(getClass().getClassLoader()
      .getResource("fileTest.txt")
      .getPath());
    File smallerFile = FileUtils.getFile(getClass().getClassLoader()
      .getResource("sample.txt")
      .getPath());
    int i = sizeFileComparator.compare(largerFile, smallerFile);
    Assert.assertTrue(i > 0);
}

7.文件监视器

Commons IO 监视器包提供了跟踪文件或目录更改的能力。让我们看一个快速示例,说明如何将FileAlterationMonitorFileAlterationObserverFileAlterationListener一起使用来监视文件或文件夹。

FileAlterationMonitor启动时,我们将开始接收有关正在监视的目录上的文件更改的通知:

FileAlterationObserver observer = new FileAlterationObserver(folder);
FileAlterationMonitor monitor = new FileAlterationMonitor(5000);
FileAlterationListener fal = new FileAlterationListenerAdaptor() {
    @Override
    public void onFileCreate(File file) {
        // on create action
    }
    @Override
    public void onFileDelete(File file) {
        // on delete action
    }
};
observer.addListener(fal);
monitor.addObserver(observer);
monitor.start();