在大目录中搜索多个文件夹 - JAVA
Searching Large Directories for Multiple Folders - JAVA
我希望能够搜索一个大目录,包括名为“online”的 every 文件夹的所有子文件夹,并添加这些文件夹一旦找到一个列表。
换句话说:这个文件是一个文件夹吗?如果没有忽略,如果是,这个文件夹叫 "online" 吗?如果是,添加到列表,如果没有打开并循环浏览文件夹内容,然后重新开始。
我有一个脚本:
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。鉴于该要求,无法使用 File
API 来做到这一点。 .listFiles()
只能以急切的方式填充目录条目。
好吧,有一种方法...如果您使用类似 Unix 的操作系统,您可以使用 ProcessBuilder
并使用诸如 find -type d -name online
之类的命令从基本目录发出进程:
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
有了Java8,就更简单了:
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());
}
我希望能够搜索一个大目录,包括名为“online”的 every 文件夹的所有子文件夹,并添加这些文件夹一旦找到一个列表。
换句话说:这个文件是一个文件夹吗?如果没有忽略,如果是,这个文件夹叫 "online" 吗?如果是,添加到列表,如果没有打开并循环浏览文件夹内容,然后重新开始。
我有一个脚本:
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。鉴于该要求,无法使用 File
API 来做到这一点。 .listFiles()
只能以急切的方式填充目录条目。
好吧,有一种方法...如果您使用类似 Unix 的操作系统,您可以使用 ProcessBuilder
并使用诸如 find -type d -name online
之类的命令从基本目录发出进程:
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
有了Java8,就更简单了:
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());
}