我使用以下 Apache Commons 类在 Java 文件系统中列出文件:
Collection<File> allFiles = FileUtils.listFiles(rootDirectory, null, recursive);
这是一个非常漫长的过程,最多可能需要 5 分钟。
有什么方法可以在填充集合时检查集合的大小?
我尝试从一个单独的线程访问它,但只是在进程准备好之前得到了零。
我使用以下 Apache Commons 类在 Java 文件系统中列出文件:
Collection<File> allFiles = FileUtils.listFiles(rootDirectory, null, recursive);
这是一个非常漫长的过程,最多可能需要 5 分钟。
有什么方法可以在填充集合时检查集合的大小?
我尝试从一个单独的线程访问它,但只是在进程准备好之前得到了零。
在您从该方法获得返回值之前,您将无法访问填充的集合,因为您无权访问此方法在内部使用的变量。
您可以通过不使用递归标志将搜索分成更小的部分,并自己处理递归以接收每个目录的集合。
如果您使用的FileVisitor
是 Java 7,一个更好的选择是使用接口来探索文件系统。它有一些回调方法可以让您跟踪进度。
您可以使用 FileUtils IOFileFilter。
Collection<File> listFiles = FileUtils.listFiles(new File("."), counter, FileFilterUtils.trueFileFilter());
柜台将在哪里
IOFileFilter counter = new IOFileFilter() {
@Override
public boolean accept(File arg0, String arg1) {
countCall();
return true;
}
@Override
public boolean accept(File arg0) {
countCall();
return true;
}
};
countCall 是更新进度的方法。
我想您可以尝试使用执行平台特定的命令,例如将列表命令输出重定向到临时文件并使用 Java File API 读取它。
ls > temp.txt
我创建了一个简单的 shell 脚本,它将列出给定索引中的文件。
#!/bin/bash
RANGE_UP=$2
RANGE_BOT=$1
CURRENT_CNTR=0
FILENAME=._m_ls
ls -w 1 > $FILENAME
while read line
do
if [ $CURRENT_CNTR -le $RANGE_UP -a $CURRENT_CNTR -gt $RANGE_BOT ]; then
printf $line"\n"
fi
CURRENT_CNTR=`expr $CURRENT_CNTR + 1`
done < $FILENAME
您现在可以执行类似的操作./ls_range.sh 10000 30000 >temp.txt
,然后使用BufferedReader
不同的线程从该文件中读取。
您执行此操作的唯一方法(与 java7 或之前建议的拆分工作相反)是编写您自己的代码以在更新回调时搜索文件系统。
我使用了来自 的代码commons-io
,并对其进行了修改以满足您的需求,显然它需要测试,但它会在找到文件时对其进行计数。
例子
interface Counter {
void foundFile(File file);
}
final class FileSearcher {
public static Collection<File> listFiles(File root, FileFilter filter, Counter counter) {
Collection<File> files = new ArrayList<File>();
File[] found = root.listFiles(filter);
if (found != null) {
for (int i = 0; i < found.length; i++) {
if (found[i].isDirectory()) {
files.addAll(listFiles(found[i], filter, counter));
} else {
files.add(found[i]);
counter.foundFile(found[i]);
}
}
}
return files;
}
}
然后像这样使用它:
final AtomicInteger inte = new AtomicInteger(0);
FileSearcher.listFiles(new File("C:/"), null, new Counter() {
@Override
public void foundFile(File file) {
System.out.println("found file number " + inte.addAndGet(1));
}
});