Pyr*_*cal 17 java performance directory-walk
我试图一次处理一个通过网络存储的文件.由于缓冲不是问题,因此读取文件很快.我遇到的问题只是列出文件夹中的目录.在许多文件夹中,每个文件夹至少有10k个文件.
由于File.list()返回数组而不是iterable,因此性能非常慢.Java关闭并收集文件夹中的所有名称,并在返回之前将其打包到数组中.
这个错误条目是http://bugs.sun.com/view_bug.do;jsessionid=db7fcf25bcce13541c4289edeb4?bug_id=4285834并且没有解决方法.他们只是说这已经为JDK7修复了.
几个问题:
虽然它不漂亮,但我通过在启动我的应用程序之前将dir/ls的输出传递给文件并传入文件名来解决这种问题.
如果你需要在应用程序中执行它,你可以使用system.exec(),但它会产生一些肮脏.
您询问.第一种形式将非常快,第二种形式也应该非常快.
确保每行执行一项(裸露,无装饰,无图形),完整路径并递归所选命令的选项.
编辑:
只需30分钟即可获得目录列表,哇.
让我感到震惊的是,如果你使用exec(),你可以将它的stdout重定向到管道而不是将其写入文件.
如果您这样做,您应该立即开始获取文件,并能够在命令完成之前开始处理.
这种互动实际上可能会减慢速度,但也许不会 - 你可能会尝试一下.
哇,我刚刚为你找到.exec命令的语法并遇到了这个,可能正是你想要的(它使用exec和"ls"列出一个目录并将结果传递到你的程序中进行处理): 良好的链接在韦巴克(约尔格在评论提供给替换这一个来自太阳,甲骨文爆发)
无论如何,这个想法是直截了当的,但正确的代码是令人讨厌的.我将从互联网中窃取一些代码并将其破解 - brb
/**
* Note: Only use this as a last resort! It's specific to windows and even
* at that it's not a good solution, but it should be fast.
*
* to use it, extend FileProcessor and call processFiles("...") with a list
* of options if you want them like /s... I highly recommend /b
*
* override processFile and it will be called once for each line of output.
*/
import java.io.*;
public abstract class FileProcessor
{
public void processFiles(String dirOptions)
{
Process theProcess = null;
BufferedReader inStream = null;
// call the Hello class
try
{
theProcess = Runtime.getRuntime().exec("cmd /c dir " + dirOptions);
}
catch(IOException e)
{
System.err.println("Error on exec() method");
e.printStackTrace();
}
// read from the called program's standard output stream
try
{
inStream = new BufferedReader(
new InputStreamReader( theProcess.getInputStream() ));
processFile(inStream.readLine());
}
catch(IOException e)
{
System.err.println("Error on inStream.readLine()");
e.printStackTrace();
}
} // end method
/** Override this method--it will be called once for each file */
public abstract void processFile(String filename);
} // end class
谢谢IBM的代码捐赠者
如何使用File.list(FilenameFilter filter)方法并实现FilenameFilter.accept(File dir,String name)处理每个文件并返回false。
我在Linux vm上运行了包含10K +文件的目录,这花费了<10秒的时间。
import java.io.File;
import java.io.FilenameFilter;
public class Temp {
private static void processFile(File dir, String name) {
File file = new File(dir, name);
System.out.println("processing file " + file.getName());
}
private static void forEachFile(File dir) {
String [] ignore = dir.list(new FilenameFilter() {
public boolean accept(File dir, String name) {
processFile(dir, name);
return false;
}
});
}
public static void main(String[] args) {
long before, after;
File dot = new File(".");
before = System.currentTimeMillis();
forEachFile(dot);
after = System.currentTimeMillis();
System.out.println("after call, delta is " + (after - before));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13495 次 |
| 最近记录: |