我希望能够搜索大型目录,包括名为“在线”的每个文件夹的所有子文件夹,并将找到的文件夹添加到列表中。
换句话说:这个文件是文件夹吗?如果不是忽略,如果是,这个文件夹名为“在线”?,如果是,则添加到列表,如果没有打开并循环浏览文件夹内容并重新开始。
我有一个脚本:
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更新代码
答案 0 :(得分:0)
不幸的是,你说你只限于Java 6.鉴于这个要求,没有办法使用File
API来做到这一点。 .listFiles()
只能以热切的方式填充目录条目。
好吧,有一种方法......如果您使用类似Unix的操作系统,您可以使用ProcessBuilder
并使用find -type d -name online
之类的命令从基本目录发出进程:< / p>
final File baseDir = ...;
final ProcessBuilder pb = new ProcessBuilder(
"find", "-type", "d", "-name", "online"
);
pb.directory(baseDir);
final Process p = pb.start();
// use the Process' InputStream
如果你使用Java 7+,你会有更轻松的时间;对FileVisitor
进行编程以收集到列表中:
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)
{
if (path.getFileName().toString().equals("online"))
list.add(path);
return FileVisitResult.CONTINUE;
}
}
// ...
final Path baseDir = Paths.get(...);
final List<Path> dirList = new ArrayList<>();
final FileVisitor<Path> visitor = new DirectoryCollectorVisitor(list);
Files.walkFileTree(baseDir, visitor);
// dirList is not filled with the entries
使用Java 8,它更加简单:
private static final BiPredicate<Path, BasicFileAttributes> ONLINE_DIRS
= (path, attrs) -> attrs.isDirectory()
&& path.getFileName().toString().equals("online");
// ...
final Path baseDir = Paths.get(...);
final List<Path> dirList;
try (
final Stream<Path> stream = Files.find(baseDir, Integer.MAX_VALUE,
ONLINE_DIRS);
) {
dirList = stream.collect(Collectors.toList());
}