我试图列出某个目录中的所有目录和文件,但“D:\ data”工作时,“D:\”不会。 “D”是辅助磁盘。
这是一个例外:
public static List<File> listf(String directoryName) throws IOException {
File directory = new File(directoryName);
List<File> resultList = new ArrayList<File>();
// get all the files from a directory
File[] fList = directory.listFiles();
resultList.addAll(Arrays.asList(fList));
for (File file : fList) {
if (file.isFile()) {
System.out.println(file.getAbsolutePath());
try {
System.out.println(scavenger.checkmime(file.getAbsolutePath()));
} catch (Exception ex) {
}
} else if (file.isDirectory()) {
resultList.addAll(listf(file.getAbsolutePath()));
}
}
// System.out.println(fList);
return resultList;
}
public static String checkmime(String fl) throws MalformedURLException, IOException {
File file = new File(fl);
String mimeType = file.toURL().openConnection().getContentType();
// System.out.println(mimeType);
return mimeType;
}
代码:
{{1}}
我的代码出了什么问题?
答案 0 :(得分:1)
在你的递归中,你永远不会要求空值。做它,它应该像这样运行:
public static List<File> listf(String directoryName) throws IOException {
File directory = new File(directoryName);
List<File> resultList = new ArrayList<>();
// get all the files from a directory
File[] fList = directory.listFiles();
// this was missing
if (fList == null) {
return null;
}
resultList.addAll(Arrays.asList(fList));
for (File file : fList) {
if (file.isFile()) {
System.out.println(file.getAbsolutePath());
try {
System.out.println(checkmime(file.getAbsolutePath()));
} catch (Exception ex) {
}
} else if (file.isDirectory()) {
// ask here if it was null
List<File> files = listf(file.getAbsolutePath());
if (files != null) {
resultList.addAll(files);
}
}
}
//System.out.println(fList);
return resultList;
}
在Windows系统的每个驱动器根目录中都有一个名为$ RECYCLE.BIN的隐藏文件夹结构。在此文件夹中,Windows为每个用户(sid)存储一个包含已删除数据的自己的文件夹(链接到它)。但普通用户只能获得第一级而不是用户文件夹(sid值作为名称)。
(德语Windows:Papierkorb = Trash)
在树中执行此类搜索的更好方法是在目录树上创建迭代器(如复合迭代器)。此解决方案也仅使用Java NIO功能,因此平台应该可以更改(没有经过测试!)。 Linux操作系统。
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
public class DirectoryTreeIterator implements Iterator<Path> {
private final Deque<Iterator<Path>> deque = new ArrayDeque<>();
public DirectoryTreeIterator(Iterator<Path> it) {
deque.push(it);
}
@Override
public boolean hasNext() {
if (deque.isEmpty()) {
return false;
} else {
Iterator<Path> it = deque.peek();
if (!it.hasNext()) {
deque.pop();
return hasNext();
} else {
return true;
}
}
}
@Override
public Path next() {
if (hasNext()) {
Iterator<Path> it = deque.peek();
Path p = it.next();
try {
// here is the magic recursive on only filtered paths
if (Files.isDirectory(p) && Files.isReadable(p) && !Files.isHidden(p)) {
deque.push(Files.newDirectoryStream(p).iterator());
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return p;
} else {
return null;
}
}
}
然后你可以像魅力一样使用它:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
public class FileLister {
public static void main(String[] args) throws IOException {
Path p = Paths.get("D:\\");
Iterator<Path> it = Files.newDirectoryStream(p).iterator();
DirectoryTreeIterator dti = new DirectoryTreeIterator(it);
while (dti.hasNext()) {
Path path = dti.next();
if (!Files.isDirectory(path)) {
String mime = Files.probeContentType(path);
System.out.println("Mime of File "
+ path.getFileName() + " is: " + mime);
}
}
}
}
答案 1 :(得分:1)
如果您在directory.listFiles()
电话下面添加此代码:
if (fList == null) {
System.out.println("Couldn't read files in directory: " + directoryName);
return resultList;
}
然后你会收到这样的信息:
无法读取目录中的文件:G:\ $ RECYCLE.BIN \ Windows SID
对于本地计算机上的用户,此 Windows SID 为security identifier。
这意味着您的当前用户无权在“回收站”目录中读取此目录(它属于其他用户),因此listFiles()
将返回null
而不是String[]
。
您可以保留检查和我发布的消息,或者您可以采用不同的方式来处理“不可读”的目录。
关于"D:\\"
失败和"D:\\data"
失败的原因:
"D:\\"
包含提及“$ RECYCLE.BIN”目录且访问受限"D:\\data"
没有当前用户不允许访问/阅读的目录,因此listFiles()
从未返回null
。