文章摘要(AI生成)
Commons-IO 包含实用工具类、字节序类、行迭代器、文件过滤器、文件比较器和流实现。实用工具类IOUtilsIOUtils 包含处理读取、写入和复制的实用方法。 这些方法适用于 InputStream、OutputStream、Reader 和 Writer。 例如,考虑从 URL 读取字节并
Commons-IO 包含实用工具类、字节序类、行迭代器、文件过滤器、文件比较器和流实现。
实用工具类
IOUtils
IOUtils 包含处理读取、写入和复制的实用方法。 这些方法适用于 InputStream、OutputStream、Reader 和 Writer。 例如,考虑从 URL 读取字节并打印它们的任务。 这通常会这样做:
InputStream in = new URL( "https://commons.apache.org" ).openStream();
try {
InputStreamReader inR = new InputStreamReader( in );
BufferedReader buf = new BufferedReader( inR );
String line;
while ( ( line = buf.readLine() ) != null ) {
System.out.println( line );
}
} finally {
in.close();
}
使用 IOUtils 类,可以通过以下方式完成:
InputStream in = new URL( "https://commons.apache.org" ).openStream();
try {
System.out.println( IOUtils.toString( in ) );
} finally {
IOUtils.closeQuietly(in);
}
在某些应用领域,这样的IO操作很常见,这个类可以节省大量的时间。 您可以依赖经过良好测试的代码。
对于这样的实用程序代码,灵活性和速度是最重要的。 但是,您还应该了解这种方法的局限性。 使用上述技术读取 1GB 文件将导致尝试创建 1GB 字符串对象!
FileUtils
FileUtils 类包含用于处理 File 对象的实用方法。 这些包括读取、写入、复制和比较文件。
例如,要逐行读取整个文件,您可以使用:
File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");
FilenameUtils
FilenameUtils 类包含在不使用 File 对象的情况下处理文件名的实用方法。 该课程旨在在 Unix 和 Windows 之间保持一致,以帮助这些环境之间的转换(例如从开发转移到生产)。
例如,要规范化删除双点段的文件名:
String filename = "C:/commons/io/../lang/project.xml";
String normalized = FilenameUtils.normalize(filename);
// result is "C:/commons/lang/project.xml"
FileSystemUtils
FileSystemUtils 类包含使用文件系统访问 JDK 不支持的功能的实用方法。 目前,唯一的方法是获取驱动器上的可用空间。 请注意,这使用命令行,而不是本机代码。
例如要查找驱动器上的可用空间:
long freeSpace = FileSystemUtils.freeSpace("C:/");
字节序类
不同的计算机体系结构采用不同的字节排序约定。 在所谓的“Little Endian”架构(例如 Intel)中,低位字节存储在内存中的最低地址,随后的字节存储在更高地址。 对于“Big Endian”架构(例如摩托罗拉),情况正好相反。
这个相关包中有两个类:
EndianUtils
类包含用于交换 Java 原语和流的 Endian-ness
的静态方法。
SwappedDataInputStream
类是 DataInput
接口的实现。 有了这个,人们可以从非本地字节序的文件中读取数据。
行迭代器
org.apache.commons.io.LineIterator
类提供了一种灵活的方式来处理基于行的文件。 实例可以直接创建,也可以通过 FileUtils
或IOUtils
上的工厂方法创建。 推荐的使用模式是:
LineIterator it = FileUtils.lineIterator(file, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
/// do something with line
}
} finally {
LineIterator.closeQuietly(iterator);
}
文件过滤器
org.apache.commons.io.filefilter
包定义了一个接口(IOFileFilter
),它结合了 java.io.FileFilter
和 java.io.FilenameFilter
。 除此之外,该软件包还提供了 IOFileFilter
接口的一系列即用型实现,包括允许您组合其他此类过滤器的实现。 例如,这些过滤器可用于列出文件或在 FileDialog
中。
有许多“原始”过滤器:
DirectoryFilter | Only accept directories |
---|---|
PrefixFileFilter | 基于前缀过滤 |
SuffixFileFilter | 基于后缀过滤 |
NameFileFilter | 根据文件名过滤 |
WildcardFileFilter | 基于通配符过滤 |
AgeFileFilter | 根据文件的最后修改时间过滤 |
SizeFileFilter | 根据文件大小过滤 |
并且有五个“布尔”过滤器:
TrueFileFilter | 接受所有文件 |
---|---|
FalseFlieFilter | 不接受任何文件 |
NotFileFilter | 将逻辑 NOT 应用于现有过滤器 |
AndFileFilter | 使用逻辑 AND 组合两个过滤器 |
OrFileFilter | 使用逻辑 OR 组合两个过滤器 |
使用传统IO
这些布尔文件名过滤器可以嵌套,以允许任意表达式。 例如,下面是如何打印当前目录中的所有非目录文件,以“A”开头,以“.java”或“.class”结尾:
File dir = new File(".");
String[] files = dir.list(
new AndFileFilter(
new AndFileFilter(
new PrefixFileFilter("A"),
new OrFileFilter(
new SuffixFileFilter(".class"),
new SuffixFileFilter(".java")
)
),
new NotFileFilter(
new DirectoryFileFilter()
)
)
);
for (int i=0; i<files.length; i++) {
System.out.println(files[i]);
}
您也可以使用过滤器本身的“and”、“or”和“not”方法构建过滤器树:
File dir = new File(".");
String[] files = dir.list(
new AndFileFilter(
new PrefixFileFilter("A").and(
new SuffixFileFilter(".class").or(new SuffixFileFilter(".java"))),
new DirectoryFileFilter().not()
)
);
for (int i=0; i<files.length; i++) {
System.out.println(files[i]);
}
该包还包含一个实用程序类:FileFilterUtils。 它允许您使用所有文件过滤器,而无需将它们放在导入部分中。 以下是使用 FileFilterUtils 的上述示例的外观:
File dir = new File(".");
String[] files = dir.list(
FileFilterUtils.andFileFilter(
FileFilterUtils.andFileFilter(
FileFilterUtils.prefixFileFilter("A"),
FileFilterUtils.orFileFilter(
FileFilterUtils.suffixFileFilter(".class"),
FileFilterUtils.suffixFileFilter(".java")
)
),
FileFilterUtils.notFileFilter(
FileFilterUtils.directoryFileFilter()
)
)
);
for (int i=0; i<files.length; i++) {
System.out.println(files[i]);
}
使用NIO
您可以将 java.nio.file.Files.walk()
与过滤器结合使用 Java 文件树遍历:
final Path dir = Paths.get("");
// We are interested in files older than one day
final long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new AgeFileFilter(cutoff));
//
// Walk one dir
Files.walkFileTree(dir, Collections.emptySet(), 1, visitor);
System.out.println(visitor.getPathCounters());
System.out.println(visitor.getFileList());
//
visitor.getPathCounters().reset();
//
// Walk dir tree
Files.walkFileTree(dir, visitor);
System.out.println(visitor.getPathCounters());
System.out.println(visitor.getDirList());
System.out.println(visitor.getFileList());
文件比较器
org.apache.commons.io.comarator
包为 java.io.File
提供了许多 java.util.Comparator
实现。 例如,这些比较器可用于对文件列表和数组进行排序。
排序
所有的比较器都包括方便实用的 sort(File…) 和 sort(List) 方法
例如,按名称对目录中的文件进行排序:
File[] files = dir.listFiles();
NameFileComparator.NAME_COMPARATOR.sort(files);
…或者,您可以在一行中执行此操作:
File[] files = NameFileComparator.NAME_COMPARATOR.sort(dir.listFiles());
复合比较器
CompositeFileComparator 可用于通过组合多个其他比较器来比较(并对文件列表或数组进行排序)。
例如,要按类型(即目录或文件)然后按名称对文件数组进行排序:
CompositeFileComparator comparator =
new CompositeFileComparator(
DirectoryFileComparator.DIRECTORY_COMPARATOR,
NameFileComparator.NAME_COMPARATOR);
File[] files = dir.listFiles();
comparator.sort(files);
单例实例(线程安全)
Comparator
实现有一些方便的单例(线程安全)实例可供使用:
DefaultFileComparator
- 默认文件比较:
DEFAULT_COMPARATOR
- 使用File.compareTo(File)
方法进行比较。
DEFAULT_REVERSE
- File.compareTo(File)
方法的反向比较。
DirectoryFileComparator
- 按类型(目录或文件)比较:
DIRECTORY_COMPARATOR
- 使用 File.isDirectory()
方法进行比较(目录 < 文件)。
DIRECTORY_REVERSE
- File.isDirectory()
方法的反向比较(目录>文件)。
ExtensionFileComparator
- 比较文件扩展名:
EXTENSION_COMPARATOR
- 使用 FilenameUtils.getExtension(String)
方法进行比较。
EXTENSION_REVERSE
- FilenameUtils.getExtension(String)
方法的反向比较。
EXTENSION_INSENSITIVE_COMPARATOR
- 使用 FilenameUtils.getExtension(String)
方法进行不区分大小写的比较。
EXTENSION_INSENSITIVE_REVERSE
- FilenameUtils.getExtension(String) 方法的反向不区分大小写比较。
EXTENSION_SYSTEM_COMPARATOR
- 使用 FilenameUtils.getExtension(String)
方法进行系统敏感比较。
EXTENSION_SYSTEM_REVERSE
- FilenameUtils.getExtension(String)
方法的反向系统敏感比较。
LastModifiedFileComparator
- 比较文件的最后修改日期/时间:
LASTMODIFIED_COMPARATOR
- 使用 File.lastModified()
方法进行比较。
LASTMODIFIED_REVERSE
-File.lastModified()
方法的反向比较。
NameFileComparator
- 比较文件名:
NAME_COMPARATOR
- 使用 File.getName()
方法进行比较。
NAME_REVERSE
- File.getName()
方法的反向比较。
NAME_INSENSITIVE_COMPARATOR
- 使用 File.getName()
方法进行不区分大小写的比较。
NAME_INSENSITIVE_REVERSE
- File.getName()
方法的反向不区分大小写比较。
NAME_SYSTEM_COMPARATOR
- 使用 File.getName()
方法进行系统敏感比较。
NAME_SYSTEM_REVERSE
- File.getName()
方法的反向系统敏感比较。
PathFileComparator
- 比较文件路径:
PATH_COMPARATOR
- 使用 File.getPath()
方法进行比较。
PATH_REVERSE
- File.getPath()
方法的反向比较。
PATH_INSENSITIVE_COMPARATOR
- 使用 File.getPath()
方法进行不区分大小写的比较。
PATH_INSENSITIVE_REVERSE
- File.getPath()
方法的反向不区分大小写比较。
PATH_SYSTEM_COMPARATOR
- 使用 File.getPath()
方法进行系统敏感比较。
PATH_SYSTEM_REVERSE
- File.getPath()
方法的反向系统敏感比较。
SizeFileComparator
- 比较文件的大小:
SIZE_COMPARATOR
- 使用 File.length()
方法进行比较(目录被视为零长度)。
LASTMODIFIED_REVERSE
- File.length()
方法的反向比较(目录被视为零长度)。
SIZE_SUMDIR_COMPARATOR
- 使用 FileUtils.sizeOfDirectory(File)
方法进行比较(对目录内容的大小求和)。
SIZE_SUMDIR_REVERSE
- FileUtils.sizeOfDirectory(File)
方法的反向比较(对目录内容的大小求和)。
流
org.apache.commons.io.input 和 org.apache.commons.io.output 包包含各种有用的流实现。 这些包括:
- 空输出流 - 静默吸收发送给它的所有数据
- Tee 输出流 - 将输出数据发送到两个流而不是一个
- 字节数组输出流 - 这是 JDK 类的更快版本
- 计数流 - 计算传递的字节数
- 代理流 - 委托给代理中的正确方法
- Lockable writer - 使用锁定文件提供写入同步
评论区