我正在使用Java 8搜索文件目录并提取音乐文件。当我在Linux(Debian Wheezy)上运行我的代码时,它在大约20秒内完成。但是,当我在Windows 8.1(相同的机器!)中运行相同的代码时,它需要非常长的时间,所以它确实无法使用。我已经确定过程正在发生,应该非常缓慢。在Linux变体找到所有2500个文件的时候,Windows变体已找到大约100个。
以下是代码:
public int List(String path) throws InterruptedException, IOException {
//Linux Variant
if (HomeScreen.os.equals("Linux")) {
File root = new File(path);
File[] list = root.listFiles();
Arrays.sort(list);
if (list == null) {
return 0;
}
for (File f : list) {
if (f.isDirectory()) {
List(f.getAbsolutePath());
} else if (f.isFile()) {
String outPath = f.getAbsolutePath();
try {
String ext = outPath.substring(outPath.lastIndexOf(".") + 1);
if (ext.equals("wma") || ext.equals("m4a") || ext.equals("mp3")) {
String fulltrack = outPath.substring(outPath.lastIndexOf("Music/") + 6);
lm.addElement(fulltrack);
numbers++;
}
} catch (Exception e) {
System.out.println(outPath + " is not a valid file!!!!!");
}
HomeScreen.Library.setModel(lm);
}
}
//Windows variant
} else if (HomeScreen.os.equals("Windows 8.1")){
System.out.println("Using " + HomeScreen.os + " methods...");
File root = new File(path);
File[] list = root.listFiles();
Arrays.sort(list);
if (list == null) {
return 0;
}
for (File f : list) {
if (f.isDirectory()) {
List(f.getAbsolutePath());
} else if (f.isFile()) {
String outPath = f.getAbsolutePath();
try {
String ext = outPath.substring(outPath.lastIndexOf(".") + 1);
if (ext.equals("wma") || ext.equals("m4a") || ext.equals("mp3")) {
String fulltrack = outPath.substring(outPath.lastIndexOf("Music/") + 9);
lm.addElement(fulltrack);
numbers++;
}
} catch (Exception e) {
System.out.println(outPath + " is not a valid file!!!!!");
}
HomeScreen.Library.setModel(lm);
}
}
}
return numbers;
}
我还是Java新手,所以我不确定如何优化Windows代码。有没有什么方法可以加速,或者Windows用户注定要喝咖啡等待加载?
顺便提一下,我在使用Windows时将此方法放在一个线程中,以便在等待时可以完成其他任务,但这绝对不是一个理想的解决方案。正在搜索的驱动器是7200转硬盘,并且安装了8GB RAM。
答案 0 :(得分:0)
尝试新的Java 8流API,它允许您执行所有操作(排序过滤器forEach) 在一个循环中! 并行:
这是你改变的代码(你可能需要修复一些我喜欢的HomeScreen部分)
Arrays.asList(root.listFiles())
.parallelStream()
.filter(file -> file != null)
.forEach(file -> {
if (file.isDirectory())
{
List(file.getAbsolutePath());
}
else if (file.isFile())
{
String outPath = file.getAbsolutePath();
try
{
String ext = outPath.substring(outPath.lastIndexOf(".") + 1);
if (ext.equals("wma") || ext.equals("m4a") || ext.equals("mp3"))
{
String fulltrack = outPath.substring(outPath.lastIndexOf("Music/") + 9);
lm.addElement(fulltrack);
numbers++;
}
} catch (Exception e)
{
System.out.println(outPath + " is not a valid file!!!!!");
}
HomeScreen.Library.setModel(lm);
}
});
答案 1 :(得分:0)
根据Lorenzo Boccaccia关联的question评论中的建议,我选择newDirectoryStream。它逐个返回文件,这应该更快。
我也考虑使用多线程。使用单个线程,您几乎一直在等待磁盘。现代磁盘能够处理多个未完成的请求,因此使用2-4个线程应该有所帮助。
旁注:没有理由为Linux和Windows编写不同的代码。可能需要进行微小的更改,但应该通过一些小帮手方法来处理。
绝不写下像
这样的内容if (HomeScreen.os.equals("Linux")) {
...
} else if (HomeScreen.os.equals("Windows 8.1")) {
...
}
如果它是" Windows 8.2"?