【发布时间】:2016-02-29 10:56:39
【问题描述】:
我希望能够搜索一个大目录,包括名为“online”的每个文件夹的所有子文件夹,并将找到的文件夹添加到列表中。 p>
换句话说:这个文件是一个文件夹吗?如果不忽略,如果是,此文件夹是否称为“在线”?如果是,则添加到列表中,如果未打开并循环浏览文件夹内容并重新开始。
我有一个脚本:
String fileType = "online";
private void buildList(File aFile) {
if (aFile.isDirectory()) {
if (fileName.contains(fileType)) {
addToList(aFile);
} else {
for (File bFile : aFile.listFiles()) {
buildList(bFile);
}
}
}
}
这适用于小目录,但不适用于大目录,因为它已打开大量数组。它挂起并用完所有内存。
我愿意接受所有建议。仅限 JAVA,理想情况下与 JDK1.6 兼容。提前非常感谢您!!!!
编辑:
static long counter = 0L;
ArrayList<File> opFolders;
public final class DirectoryCollectorVisitor extends SimpleFileVisitor<Path> {
private final List<Path> list;
public DirectoryCollectorVisitor(final List<Path> list) {
this.list = list;
}
@Override
public FileVisitResult preVisitDirectory(final Path path, final BasicFileAttributes attrs) {
counterPrintField.setText("" + counter++);
if (path.getFileName().toString().contains("online")) {
list.add(path);
File aFile = path.toFile();
opFolders.add(aFile);
}
return FileVisitResult.CONTINUE;
}
}
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser chooser = jFileChooser1;
chooser.setCurrentDirectory(new java.io.File("O:\\Prod\\Clients"));
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
int returnVal = chooser.showOpenDialog(this);
if (returnVal == chooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
try {
jTextArea1.setText(null);
opFolders = new ArrayList<>();
final Path baseDir = Paths.get(file.getAbsolutePath());
final List<Path> dirList = new ArrayList<>();
dirList.add(baseDir);
final FileVisitor<Path> visitor = new DirectoryCollectorVisitor(dirList);
Files.walkFileTree(baseDir, visitor);
if(opFolders.isEmpty()){
System.err.println("EMPTY");
}
for (File aFile : opFolders) {
if (!aFile.isDirectory() && !aFile.getName().toLowerCase().endsWith(".db")) {
jTextArea1.append(aFile.getAbsolutePath() + "\n");
}
}
jTextArea1.append("...COMPLETE...");
} catch (Exception ex) {
System.out.println("Problem accessing directory: " + file.getAbsolutePath());
}
} else {
System.out.println("File access cancelled by user.");
}
}
@fge 更新代码
【问题讨论】:
-
仅限 Java 6?太糟糕了...如果您使用 Java 7+ 会有一个解决方案。使用 Java 6,您几乎是 SOL(无法懒惰地读取目录条目)。但是现在是 2015 年,所以必须提出一个问题:为什么是 Java 6?已经有好几年了,它已经走到了生命的尽头
-
这很奇怪。定义
Large Directories -
@UmaKanth 这一点都不奇怪;想象一下一个目录层次结构,其中每个级别都有数十甚至数百个文件,并且您递归地遍历它们。由于
File的.listFiles()返回一个数组,所以它别无选择,只能急切地填充数组,这会很快导致巨大的内存消耗。从 JSR 203 和DirectoryStream开始,这不再是问题。 -
每个递归级别都会创建一个新的文件数组。仍然无法想象以这种方式遍历时会耗尽内存的目录层次结构。你能给出一些数字(目录深度、每个目录的平均文件数)吗?
-
每个文件夹可能包含数百个其他文件夹,可能包含数百个等等。我并不坚持使用 JDK1.6,尽管 JDK1.6 解决方案更适合用于仅支持 JDK1.6 的单独 informatica 项目。
标签: java search directory subdirectory