问题描述
此处是初学者Java程序员。我正在尝试在Mac(最终是Android)上制作一个简单的mp3
播放器,我希望它可以自动识别设备上已经存在的所有音乐(mp3
)。
我有一个简单的for循环设置,该循环从主目录开始,并遍历所有其他目录,以寻找mp3s
。我还没有看到它完成循环,因为我一直要强制停止它,因为它持续了很长时间。我可以排除一些文件夹,因为在其中放置音乐根本没有意义,但是我觉得有更好的方法。
还有没有其他比for
循环更快和/或更有效的方法了?
我也对Mac中的finder如何工作感到好奇。例如,当我使用查找程序在Mac上查找所有mp3
文件时,结果仅需几秒钟即可显示出来,而我所需要的只是输入一些搜索条件。如果有人可以指出要我完成类似的事情的方向,那我将尽一切可能!
public static void findAudio(File currentDir) {
File[] filesInDir = currentDir.listFiles();
if (filesInDir != null){
if (filesInDir.length == 0){
return;
}
else {
for (File file : filesInDir) {
if (!file.isHidden()) {
if (file.isDirectory()) {
findAudio(file);
}
if (file.canRead()) {
if (file.getName().endsWith(".mp3")) {
System.out.println(file.getPath());
}
}
}
}
}
}
else {
System.out.println(currentDir.getPath() + " is null -- skipping");
}
}
解决方法
首先,检查文件扩展名比检查文件是否可读更耗时。
此外,您可以为此使用Java 8中添加的Files.walkFileTree
方法。
oracle网站上有一个有关如何使用它的教程:https://docs.oracle.com/javase/tutorial/essential/io/walk.html
代码看起来像这样:
Files.walkFileTree(Paths.get(sourcePath),new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path filePath,BasicFileAttributes attrs) {
if (filePath.toString().endsWith(".mp3") && filePath.toFile().canRead()) {
System.out.println(filePath.toString());
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file,IOException exc) {
System.err.println("Failed reading \"" + file.toString() + "\" -- skipping");
return FileVisitResult.CONTINUE;
}
});
SimpleFileVisitor
类是FileVisitor
接口的简化实现,其默认行为是访问所有文件并重新引发I / O错误。
如果发生I / O错误,我们仅将文件路径打印到默认错误流,然后继续进行文件处理。
如果没有错误,文件扩展名是“ .mp3”(如上所述,首先检查扩展名),并且文件可读,我们将文件路径打印到默认输出流(您还可以执行其他操作,例如将其添加到媒体文件列表中
,import java.io.*;
public static void extract(String p) {
File f = new File(p);
File l[] = f.listFiles();
for(File x : l){
if (x==null) return;
if (x.isHidden()||!x.canRead()) continue;
if (x.isDirectory()) extract(x.getPath());
else if (x.getName().endsWith(".mp3"))
System.out.println(x.getPath()+"\\"+x.getName());
}
}