Java:列出目录中的文件
介绍
文件处理是大多数应用程序的核心功能之一,也是任何编程语言中的基础知识点。
为了操作文件,我们首先需要知道它们的位置。因此,能够概览目录中的文件结构至关重要,尤其是当我们希望通过迭代对这些文件执行操作时。在 Java 中,有多种方法可以实现这一目标,本文将逐一介绍。
为了便于理解,本文所有示例均基于以下文件树结构:
Programming
|-- minimax.c
|-- super_hack.py
|-- TODO.txt
`-- CodingMusic
|-- Girl Talk - All Day.mp3
|-- Celldweller - Frozen.mp3
|-- Lim Taylor - Isn't It Wonderful.mp3
`-- Radiohead - Everything in Its Right Place.mp3File.list()
在不遍历子目录的情况下,列出给定目录中文件和文件夹名称的最简单方法是使用 File 类的辅助方法 .list()。该方法返回一个 String 数组。
我们可以通过在 File 实例上调用 .list() 方法来执行此操作:
public class Pathnames {
public static void main(String[] args) {
// 创建一个数组用于存储文件和目录的名称
String[] pathnames;
// 通过将给定的路径名字符串转换为抽象路径名,创建一个新的 File 实例
File f = new File("D:/Programming");
// 用文件和目录的名称填充数组
pathnames = f.list();
// 遍历 pathnames 数组中的每个路径名
for (String pathname : pathnames) {
// 打印文件和目录的名称
System.out.println(pathname);
}
}
}使用简单的 foreach 循环,我们遍历数组并打印出 String 数组中的内容。
CodingMusic
minimax.c
super_hack.py
TODO.txt使用这种方法时,CodingMusic 目录中的所有子项都不会显示出来。这种方法的局限性在于我们只能获取文件名,无法直接对文件对象本身进行操作。当我们仅需查看文件表面信息(如文件名)时,这种方法非常有用。
FilenameFilter
利用 .list() 方法,我们还可以创建一个 FilenameFilter 来仅返回符合特定条件的文件:
File f = new File("D:/Programming");
// 此过滤器仅包含以 .py 结尾的文件
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File f, String name) {
return name.endsWith(".py");
}
};
// 应用过滤器
pathnames = f.list(filter);运行这段代码将产生以下输出:
super_hack.pyFile.listFiles()
与前一种方法类似,该方法也可用于返回文件和目录的名称。不同的是,这次我们将它们作为 File 对象数组获得,这使我们能够直接操作文件对象本身:
public class Pathnames {
public static void main(String args[]) {
// 使用 try-catch 块处理异常
try {
File f = new File("D:/Programming");
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File f, String name) {
// 我们只想查找 .c 文件
return name.endsWith(".c");
}
};
// 注意这次我们使用的是 File 类数组,而不是 String
File[] files = f.listFiles(filter);
// 使用 .getName() 方法获取文件名
for (int i = 0; i < files.length; i++) {
System.out.println(files[i].getName());
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}输出:
minimax.c现在,让我们使用递归遍历文件系统,并在 File 对象上使用更多方法(如获取文件大小):
public class ListFilesRecursively {
public void listFiles(String startDir) {
File dir = new File(startDir);
File[] files = dir.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
// 检查文件是否为目录
if (file.isDirectory()) {
// 不打印目录名,仅将其作为新的起点继续列出文件
listFiles(file.getAbsolutePath());
} else {
// 我们可以使用 .length() 获取文件大小
System.out.println(file.getName() + " (size in bytes: " + file.length() + ")");
}
}
}
}
public static void main(String[] args) {
ListFilesRecursively test = new ListFilesRecursively();
String startDir = "D:/Programming";
test.listFiles(startDir);
}
}输出:
Girl Talk - All Day.mp3 (size in bytes: 8017524)
Celldweller - Frozen.mp3 (size in bytes: 12651325)
Lim Taylor - Isn't It Wonderful.mp3 (size in bytes: 6352489)
Radiohead - Everything in Its Right Place.mp3 (size in bytes: 170876098)
minimax.c (size in bytes: 20662)
super_hack.py (size in bytes: 114401)
TODO.txt (size in bytes: 998)Files.walk()
在 Java 8 及更高版本中,我们可以使用 java.nio.file.Files 类填充一个 Stream(流),并利用它遍历文件和目录,同时递归访问所有子目录。
请注意,在此示例中我们将使用 Lambda 表达式:
public class FilesWalk {
public static void main(String[] args) {
try (Stream<Path> walk = Files.walk(Paths.get("D:/Programming"))) {
// 我们只想查找普通文件
List<String> result = walk.filter(Files::isRegularFile)
.map(x -> x.toString()).collect(Collectors.toList());
result.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}在这里,我们使用 .walk() 方法填充了一个 Stream,并传递了一个 Paths 参数。Paths 类通过静态方法返回基于 URI 字符串的 Path 对象——使用 Path,我们可以更便捷地定位文件。
Path、Paths、Files 等类属于 java.nio 包,这是 Java 7 中引入的用于表示文件系统的更现代方式(NIO.2)。
随后,我们使用 Collections Framework 生成一个列表。
运行这段代码将产生:
D:\Programming\Coding Music\Radiohead - Everything in Its Right Place.mp3
D:\Programming\Coding Music\Lim Taylor - Isn't It Wonderful.mp3
D:\Programming\Coding Music\Celldweller - Frozen.mp3
D:\Programming\Coding Music\Girl Talk - All Day.mp3
D:\Programming\minimax.c
D:\Programming\super_hack.py
D:\Programming\TODO.txt结论
以某种方式处理文件是大多数编程语言的核心任务,这包括在文件系统中列出和查找文件的能力。为了操作文件,我们需要知道它们的位置。如果要完成此任务,那么对目录中的文件进行概述是至关重要的,特别是如果我们可以通过迭代对其执行操作的话。
在本文中,我们展示了使用单层遍历、递归方法以及 Java 8 Stream API 在 Java 中列出文件系统上文件的多种不同方法。
说明:
File类属于早期 Java IO API,而Files、Path属于 Java 7 引入的 NIO.2 API。Files.walk()方法需要 Java 8 或更高版本。- 示例中的路径格式(如
D:/Programming)适用于 Windows 系统,在 Linux 或 macOS 上需调整为相应路径格式。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/java-lie-chu-mu-lu-zhong-de-wen-jian.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。