Java目录/文件列表

时间:2015-06-20 08:13:58

标签: java file dir

我试图列出某个目录中的所有目录和文件,但“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}}

我的代码出了什么问题?

2 个答案:

答案 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;
  }

为什么D:\ data有效,D:\

在Windows系统的每个驱动器根目录中都有一个名为$ RECYCLE.BIN的隐藏文件夹结构。在此文件夹中,Windows为每个用户(sid)存储一个包含已删除数据的自己的文件夹(链接到它)。但普通用户只能获得第一级而不是用户文件夹(sid值作为名称)。

(德语Windows:Papierkorb = Trash)

enter image description here

一个可能更好的解决方案:

在树中执行此类搜索的更好方法是在目录树上创建迭代器(如复合迭代器)。此解决方案也仅使用Java NIO功能,因此平台应该可以更改(没有经过测试!)。 Linux操作系统。

DirectoryTreeIterator.java

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;
    }
  }

}

然后你可以像魅力一样使用它:

FileLister.java

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