[Java SE] 基础工具库 : Apache Commons IO

1 总述

  • Commons IOApache Commons IO)是一个广泛用于 Java 开发的开源工具库,由Apache软件基金会维护和支持。这个库旨在简化文件和流操作,提供了各种实用工具类和方法,以便更轻松地进行输入输出操作。以下是 Commons IO 的一些主要特点和功能:
  1. 文件操作:Commons IO 提供了大量用于文件和目录操作的方法,包括创建、删除、重命名、复制、移动文件,以及递归地操作目录结构。
  2. 流处理:你可以使用 Commons IO 处理各种输入和输出流,包括读取、写入和操作流数据。这对于处理文本文件、二进制文件以及网络通信非常有用。
  3. 文件过滤和筛选:Commons IO 允许你轻松地筛选文件和目录,根据各种条件,如文件扩展名、文件大小、最后修改时间等。
  4. 文件内容操作:你可以比较两个文件的内容,查找文件中的文本,以及进行替换等操作。
  5. 自动关闭流:Commons IO 提供了自动关闭流的功能,确保在处理文件和流时,资源得以正确释放,而无需显式调用close()方法。
  6. 异常处理:库中的方法通常会处理 I/O 异常,以简化代码中的错误处理。
  7. 性能和可靠性:Commons IO 被广泛使用,因为它经过了精心设计,以提供高性能和可靠性。这对于处理大型文件和在生产环境中运行的应用程序非常重要。

它可以显著简化日常的 I/O 任务,减少了编写重复性代码的需要,提高了开发效率。如果你是 Java 开发者,特别是在处理文件和流方面,建议考虑使用 Commons IO 来简化你的工作。你可以在 Apache Commons IO 的官方网站上找到详细的文档和示例代码,以了解如何使用这个库。

  • dependency import

commons.io.version : 1.11.0

<!-- https://commons.apache.org/proper/commons-io/ -->
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>${commons.io.version}</version>
	<scope>provided</scope>
</dependency>

如下坐标已废止、不建议使用:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-io</artifactId>
    <version>1.3.2</version>
</dependency>
  • 核心工具类 : org.apache.commons.io.FilenameUtils
@Test  
public void test(){  
    //String filePath = FilenameUtils.concat("/base-dir/", "/demo-file.txt");//[x] 错误示范 , out : /demo-file.txt    String filePath = FilenameUtils.concat("/base-dir/", "demo-file.txt");// out : \\base-dir\\demo-file.txt  
    log.info("filePath : {}", filePath);//filePath : \\base-dir\\demo-file.txt  
  
    Boolean equalsResult = FilenameUtils.equals("/base-dir/a", "/base-dir/b");  
    log.info("equalsResult : {}", equalsResult);//equalsResult : false  
}
  • 核心工具类 : org.apache.commons.io.FileUtils
  • 核心工具类 : org.apache.commons.io.IOUtils
  • 核心工具类 : org.apache.commons.io.file.PathUtils

2 核心方法

查找、获取操作

获取操作系统文件分隔符

用于获取操作系统的文件分隔符,例如,在 Windows 中是反斜杠(\),在 Unix/Linux 中是正斜杠(/)。

String fileSeparator = File.separator;

获取指定文件

//获取指定路径下的文件
File file = FileUtils.getFile("D://test/test-dir/123.txt");

File file = FileUtils.getFile("log4j2.properties");// file.getCanonicalPath() : //E:\source_code\XXX\xxx-bigdata\xxx-common-utils\log4j2.properties

//获取指定目录下的文件
File file1 = FileUtils.getFile(new File("D://test/test-dir"), "123.txt", "456.txt");

获取文件,等待指定时长至其存在

//等待一个文件xx秒,知道文件创建后才返回。每max(100,remainning)循环检查一次
while (FileUtils.waitFor(new File("D://test/test1"), 60)) {
	//...
}

递归列出目录中的文件和子目录

File directory = new File("parentDir");
Collection<File> allFilesAndDirs = FileUtils.listFilesAndDirs(directory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);

用于递归列出目录中的所有文件和子目录。

列出目录中的文件

File directory = new File("directory");
String[] filesInDir = directory.list();

用于获取指定目录中的文件和子目录的名称列表。

查找文件

用于在目录中查找文件,并将结果作为文件对象的集合返回。

File searchDir = new File("searchDir");
Collection<File> foundFiles = FileUtils.listFiles(searchDir, TrueFileFilter.TRUE, TrueFileFilter.TRUE);

获取文件大小

File file = new File("file.txt"); 
long fileSize = FileUtils.sizeOf(file);//返回 Long

FileUtils.sizeOfAsBigInteger(file);//返回 BigInteger

获取文件的大小的可读表示

用于将文件大小以字节表示转换为易读的格式,例如 "2.5 MB"。

EB, PB, TB, GB, MB, KB or bytes

File file = new File("file.txt"); 
String readableSize = FileUtils.byteCountToDisplaySize(file.length());

获取文件的扩展名(不包括点号)

用于获取文件的扩展名,不包括点号,例如,对于 "example.txt",将返回 "txt"。

String fileName = "example.txt";
String extension = FilenameUtils.getExtension(fileName);//txt

获取文件的创建时间

File file = new File("file.txt");
BasicFileAttributes attributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
FileTime creationTime = attributes.creationTime();

获取文件的最后修改时间

File file = new File("file.txt"); 
long lastModified = file.lastModified(); // 获取
//file.setLastModified(System.currentTimeMillis()) // 设置

获取文件的最后访问时间

用于获取文件的最后访问时间,以毫秒为单位。

File file = new File("file.txt"); 
long lastAccessTime = FileUtils.lastAccessed(file);

判断、检查/比较

判断文件是否是隐藏文件

File file = new File("hiddenFile.txt");
boolean isHidden = file.isHidden();

判断是否为符号链接文件

FileUtils.isSymlink(new File("D://test/test1"));

检查文件是否可写

File file = new File("writableFile.txt"); 
boolean isWritable = file.canWrite();

比较文件内容

用于比较两个文件的内容是否相同。

File file1 = new File("file1.txt");
File file2 = new File("file2.txt");
boolean contentEqual = FileUtils.contentEquals(file1, file2);

//FileUtils.contentEqualsIgnoreEOL(new File("D://test/test1"), new File("D://test/test2"), null);//忽略换行符,第3个参数是字符集

比较目录结构

用于比较两个目录的内容是否相同,忽略不同操作系统的换行符。

File dir1 = new File("directory1");
File dir2 = new File("directory2");
boolean isSame = FileUtils.contentEqualsIgnoreEOL(dir1, dir2, "UTF-8");

创建、移动/重命名、拷贝、删除

创建目录

用于创建目录,包括创建任何中间目录(如果它们不存在)。

File newDir = new File("newDir"); 
FileUtils.forceMkdir(newDir);

创建文件

创建文件,如果文件存在则更新时间;如果不存在,创建一个空文件

FileUtils.touch(new File("D://test/test4"));

移动文件

用于将文件从一个位置移动到另一个位置。

File oldFile = new File("oldFile.txt"); 
File newFile = new File("newFile.txt"); 
FileUtils.moveFile(oldFile, newFile);

文件重命名

File oldFile = new File("oldName.txt"); 
File newFile = new File("newName.txt"); 
FileUtils.moveFile(oldFile, newFile);

拷贝文件

File source = new File("source.txt");
File destination = new File("destination.txt");
FileUtils.copyFile(source, destination);

//案例:将b文件夹下a.doc拷贝到mm下a.doc,前者不存在会报错,后者不存在会新建;如果后者存在同名文件则替换
//FileUtils.copyFile(new File("d:/b/a.doc"), new File("d:/b/mm/a.doc"));
//FileUtils.copyFile(new File("d:/b/a.doc"), new File("d:/b/mm","a.doc"));//与上一方式等效

文件拷贝,但保留原文件的属性

用于拷贝文件,保留原文件的属性,如权限和时间戳。

File source = new File("source.txt");
File destination = new File("destination.txt");
FileUtils.copyFile(source, destination, true);

拷贝输入流到输出流

用于将输入流的内容拷贝到输出流,通常用于文件拷贝。

InputStream inputStream = ...; // 初始化输入流
OutputStream outputStream = ...; // 初始化输出流
IOUtils.copy(inputStream, outputStream);

拷贝文件内容到输出流

用于将文件内容拷贝到输出流,这样你可以将文件的内容传输到其他地方,如网络连接或压缩流。

File sourceFile = new File("source.txt");
OutputStream outputStream = ...; // 初始化输出流
FileUtils.copyFile(sourceFile, outputStream);

拷贝输入流到新文件

FileUtils.copyInputStreamToFile(new FileInputStream("D://test/test1"), new File("D://test/test1"));

拷贝URL内容到新文件

FileUtils.copyURLToFile(new URL("file:/test"), new File("D://test/test1"));


## 删除操作

### 删除目录
``` java
//删除目录或文件,无法删除会抛异常
FileUtils.deleteDirectory(new File("D://test/test1"));//递归删除目录

//deleteQuietly => 安静删除目录或文件,无法删除时也不会抛异常
FileUtils.deleteQuietly(new File("D://test/test1"));//如果是目录,会级联删除;不会抛出异常,安静删除

拷贝文件夹

String filePath1 = "D://test/test1" ;
File srcDir = new File( filePath1 ) ;
 
String filePath2 = "D://test/test2" ;
File destDir = new File( filePath2 ) ;
 
try {
    //方式1: 复制文件夹(文件夹里面的文件内容也会复制)
    FileUtils.copyDirectory(srcDir, destDir);
    
    //方式2: 仅仅拷贝目录↓ (复制文件夹,带有文件过滤功能)
    //FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY);
    
    //IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");// 创建.txt过滤器
    //IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
    // 创建包含目录或者txt文件的过滤器
    //FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
    // Copy using the filter
    //FileUtils.copyDirectory(srcDir, destDir, filter);//TODO 阅读doCopyDirectory源码

    //方式3: 将目录1所有的文件夹及文件复制到目录2下,如果有同名文件夹则合并,如果有同名文件则替换
    //FileUtils.copyDirectoryToDirectory(srcDir, destDir);
} catch (IOException e) {
    e.printStackTrace();
}

拷贝文件到指定文件夹下

FileUtils.copyFileToDirectory(
        new File("C://Users/xx/Desktop/newDir/123/123.txt"),
        new File("C://Users/xx/Desktop/newDir/456")
);

递归拷贝文件

这个方法将递归地拷贝一个目录及其所有内容到目标目录。

File sourceDir = new File("sourceDir"); 
File destDir = new File("destDir"); 
FileUtils.copyDirectory(sourceDir, destDir);

递归删除目录下的指定文件

//用于递归删除指定文件名的文件
File directory = new File("parentDir"); 
String fileNameToDelete = "fileToDelete.txt"; 
FileFilter fileFilter = new NameFileFilter(fileNameToDelete); 
Collection<File> foundFiles = FileUtils.listFiles(directory, fileFilter, TrueFileFilter.TRUE); 
for (File fileToDelete : foundFiles) { 
  FileUtils.forceDelete(fileToDelete); 
}

删除文件(强制)

这个方法用于强制删除一个文件,即使它是只读的或不存在。

File fileToDelete = new File("fileToDelete.txt");
FileUtils.forceDelete(fileToDelete);

删除文件(在JVM程序退出运行时,强制)

//当JVM退出时,把file对象删除。如果是目录对象则递归删除子目录,跟delete的区别是一个是立马执行 一个是JVM退出后执行 forceDeleteOnExit 这个用来删除临时文件或缓存文件用的
try {
   File file2 = new File("C:\\Users\\Administrator\\Desktop\\sign\\");
   FileUtils.forceDeleteOnExit(file2);
} catch (Exception e) {
e.printStackTrace();
}

递归删除文件

File directoryToDelete = new File("directoryToDelete");
FileUtils.deleteDirectory(directoryToDelete);

删除目录中的文件

用于删除目录中的所有文件,但保留目录结构。

//清除目录中的内容,不会删除该目录, 遍历目录中的文件。
//如果是目录,则递归删除;如果是文件,则强制删除;删除失败(文件不存在或无法删除)都会抛出异常
File directory = new File("dirToDelete");
FileUtils.cleanDirectory(directory);

关闭输出流

用于关闭输出流,忽略任何可能的异常。

OutputStream outputStream = ...; // 初始化输出流 IOUtils.closeQuietly(outputStream);
  • 关闭 Writer
//用于关闭字符流 Writer,忽略任何可能的异常。
Writer writer = ...; // 初始化 Writer
IOUtils.closeQuietly(writer);

读取、写入操作

R 逐行读取文件内容(返回迭代器)

用于逐行读取文件内容,避免一次性加载整个文件。

File file = new File("file.txt"); 
LineIterator lines = FileUtils.lineIterator(file, "UTF-8"); 
while (lines.hasNext()) { 
    String line = lines.next(); // 处理每一行 
} 
lines.close(); // 关闭 LineIterator

R 一次性读取文件内容(返回每行的文本列表)

//读取目标文件每一行数据,返回list
List<String> strs = FileUtils.readLines(new File("D://test/test1"), "utf-8");

R 读取文件内容为字节数组

byte[] bytes = FileUtils.readFileToByteArray(new File("D://test/test1"));

R 读取文件内容为字符串

用于将文件内容读取为字符串,可以指定字符编码。

File fileToRead = new File("readMe.txt"); 
String fileContent = FileUtils.readFileToString(fileToRead, "UTF-8");
## 关闭输入流
用于关闭输入流,忽略任何可能的异常。
``` java
InputStream inputStream = ...; // 初始化输入流 IOUtils.closeQuietly(inputStream);
  • 关闭Reader
//用于关闭字符流 Reader,忽略任何可能的异常。
Reader reader = ...; // 初始化 Reader IOUtils.closeQuietly(reader);

R 读取 URL 内容到字符串

String urlContent = IOUtils.toString(new URL("https://baidu.com"));
/**
urlContent : 
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>bfe/1.0.8.18</center>
</body>
</html>
 **/

W 写入字符串到 URL

用于将字符串写入 URL。

URL url = new URL("https://example.com");
String content = "Hello, World!";
IOUtils.write(content, url.openConnection().getOutputStream(), "UTF-8");

W 写入字符串文本到文件

用于将字符串写入文件,可以指定字符编码。

File outputFile = new File("output.txt"); 
String content = "Hello, World!"; 
FileUtils.writeStringToFile(outputFile, content, "UTF-8");

//将字符串写入文件,[目标文件] [写入的文本内容] [字符集] [是否追加]
//FileUtils.writeStringToFile(new File("D://test/test1"), "file content", "utf-8", true);

//FileUtils.write(new File("D://test/test1"), "target char sequence", "utf-8", true);
//FileUtils.writeByteArrayToFile(new File("D://test/test1"), "bytes".getBytes());//(file,字符数组)
//FileUtils.writeByteArrayToFile(new File("D://test/test1"), "bytes".getBytes(), true);//(file,字符数组,是否追加)
//FileUtils.writeByteArrayToFile(new File("D://test/test1"), "bytes".getBytes(), 0, 10);//(file,字符数组,起始位置,结束位置)
//FileUtils.writeByteArrayToFile(new File("D://test/test1"), "bytes".getBytes(), 0, 10, true);//(file,字符数组,起始位置,结束位置,是否追加)

W 将文件内容追加到已存在的文件

File fileToAppend = new File("append.txt");
FileUtils.writeStringToFile(fileToAppend, "Appended Text", "UTF-8", true);

用于将文本内容附加到已存在的文件。

W 文件内容替换

File file = new File("file.txt"); 
String oldText = "replaceThis"; 
String newText = "withThis"; 
String replacedText = FileUtils.readFileToString(file, "UTF-8"); 
replacedText = StringUtils.replace(replacedText, oldText, newText); 
FileUtils.writeStringToFile(file, replacedText, "UTF-8");

临时文件(夹)操作

获取临时目录、用户主目录

  • getTempDirectoryPath :用于获取操作系统的临时目录。
  • getUserDirectoryPath :用户获取用户主目录
    • 通常是用户文件的根目录。
String tempDirectoryPath = FileUtils.getTempDirectoryPath();// C:\\Users\\xxxx\\AppData\\Local\\Temp\\

//File tempDirectory = FileUtils.getTempDirectory();//获取临时目录 的 File 对象

String userDirectoryPath = FileUtils.getUserDirectoryPath();// C:\\Users\\xx

//File userDirectory = FileUtils.getUserDirectory();//获取用户主目录 的 File 对象

获取临时文件夹的路径

用于获取操作系统的临时文件夹路径。

String tempDirPath = System.getProperty("java.io.tmpdir");//C:\\Users\\xx\\AppData\\Local\\Temp\\

创建临时目录

File tempDir = File.createTempFile("tempDir", "");
tempDir.delete(); // 删除文件,使其成为目录

创建临时文件

用于创建一个临时文件,通常在操作完成后会被自动删除。

File tempFile = File.createTempFile("temp", ".txt");

X 参考文献

  • Apache Commons IO
  1. https://commons.apache.org/proper/commons-io/
  2. https://mvnrepository.com/artifact/commons-io/commons-io
posted @ 2024-07-09 14:19  千千寰宇  阅读(40)  评论(0编辑  收藏  举报