如何遍历 Java 目录中的文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3154488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:54:59  来源:igfitidea点击:

How do I iterate through the files in a directory in Java?

java

提问by James

I need to get a list of all the files in a directory, including files in all the sub-directories. What is the standard way to accomplish directory iteration with Java?

我需要获取目录中所有文件的列表,包括所有子目录中的文件。用 Java 完成目录迭代的标准方法是什么?

采纳答案by BalusC

You can use File#isDirectory()to test if the given file (path) is a directory. If this is true, then you just call the same method again with its File#listFiles()outcome. This is called recursion.

您可以使用File#isDirectory()来测试给定的文件(路径)是否为目录。如果这是true,那么您只需再次调用相同的方法及其File#listFiles()结果。这称为递归

Here's a basic kickoff example.

这是一个基本的启动示例。

public static void main(String... args) {
    File[] files = new File("C:/").listFiles();
    showFiles(files);
}

public static void showFiles(File[] files) {
    for (File file : files) {
        if (file.isDirectory()) {
            System.out.println("Directory: " + file.getName());
            showFiles(file.listFiles()); // Calls same method again.
        } else {
            System.out.println("File: " + file.getName());
        }
    }
}

Note that this is sensitive to StackOverflowErrorwhen the tree is deeper than the JVM's stack can hold. You may want to use an iterative approach or tail-recursioninstead, but that's another subject ;)

请注意,这StackOverflowError对树的深度超过 JVM 堆栈可以容纳的时间很敏感。您可能想改用迭代方法或尾递归,但这是另一个主题;)

回答by duffymo

It's a tree, so recursion is your friend: start with the parent directory and call the method to get an array of child Files. Iterate through the child array. If the current value is a directory, pass it to a recursive call of your method. If not, process the leaf file appropriately.

它是一棵树,因此递归是您的朋友:从父目录开始并调用该方法以获取子文件数组。遍历子数组。如果当前值是一个目录,则将其传递给您的方法的递归调用。如果没有,请适当处理叶文件。

回答by Ben J

Check out the FileUtilsclass in Apache Commons - specifically iterateFiles:

退房的文件实用程序在Apache的百科全书类-特别iterateFiles

Allows iteration over the files in given directory (and optionally its subdirectories).

允许迭代给定目录(以及可选的其子目录)中的文件。

回答by Chimmy

As noted, this is a recursion problem. In particular, you may want to look at

如前所述,这是一个递归问题。特别是,你可能想看看

listFiles() 

In the java File API here. It returns an array of all the files in a directory. Using this along with

此处的 java File API 中。它返回一个目录中所有文件的数组。与此一起使用

isDirectory()

to see if you need to recurse further is a good start.

看看你是否需要进一步递归是一个好的开始。

回答by clstrfsck

If you are using Java 1.7, you can use java.nio.file.Files.walkFileTree(...).

如果您使用的是 Java 1.7,则可以使用java.nio.file.Files.walkFileTree(...).

For example:

例如:

public class WalkFileTreeExample {

  public static void main(String[] args) {
    Path p = Paths.get("/usr");
    FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
        System.out.println(file);
        return FileVisitResult.CONTINUE;
      }
    };

    try {
      Files.walkFileTree(p, fv);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

If you are using Java 8, you can use the stream interface with java.nio.file.Files.walk(...):

如果您使用的是 Java 8,您可以使用流接口java.nio.file.Files.walk(...)

public class WalkFileTreeExample {

  public static void main(String[] args) {
    try (Stream<Path> paths = Files.walk(Paths.get("/usr"))) {
      paths.forEach(System.out::println);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

回答by fjkjava

Using org.apache.commons.io.FileUtils

使用 org.apache.commons.io.FileUtils

File file = new File("F:/Lines");       
Collection<File> files = FileUtils.listFiles(file, null, true);     
for(File file2 : files){
    System.out.println(file2.getName());            
} 

Use false if you do not want files from sub directories.

如果您不想要来自子目录的文件,请使用 false。

回答by Wim Deblauwe

For Java 7+, there is also https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

对于 Java 7+,还有https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

Example taken from the Javadoc:

取自 Javadoc 的示例:

List<Path> listSourceFiles(Path dir) throws IOException {
   List<Path> result = new ArrayList<>();
   try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
       for (Path entry: stream) {
           result.add(entry);
       }
   } catch (DirectoryIteratorException ex) {
       // I/O error encounted during the iteration, the cause is an IOException
       throw ex.getCause();
   }
   return result;
}

回答by Raghu DV

To add with @msandiford answer, as most of the times when a file tree is walked u may want to execute a function as a directory or any particular file is visited. If u are reluctant to using streams. The following methods overridden can be implemented

要添加@msandiford 答案,因为大多数情况下遍历文件树时,您可能希望将函数作为目录或访问任何特定文件来执行。如果你不愿意使用流。可以实现以下重写的方法

Files.walkFileTree(Paths.get(Krawl.INDEXPATH), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
    new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
                throws IOException {
                // Do someting before directory visit
                return FileVisitResult.CONTINUE;
        }
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException {
                // Do something when a file is visited
                return FileVisitResult.CONTINUE;
        }
        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc)
                throws IOException {
                // Do Something after directory visit 
                return FileVisitResult.CONTINUE;
        }
});

回答by Rob Klinkhamer

You can also misuse File.list(FilenameFilter) (and variants) for file traversal. Short code and works in early java versions, e.g:

您还可以滥用 File.list(FilenameFilter)(和变体)进行文件遍历。短代码并适用于早期的 Java 版本,例如:

// list files in dir
new File(dir).list(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        String file = dir.getAbsolutePath() + File.separator + name;
        System.out.println(file);
        return false;
    }
});