Java中的目录导航
                    
                        2023年07月17日 由 Susan 发表
                        891225
                        0
                    
                 
                
                	我们将讨论如何使用目录、子目录,并使用 Java 和 DirectoryStream 方法遍历它们。
 
目录是包含文件和其他目录的组织文件系统结构。Java 提供了几种遍历目录的方法,具体取决于您使用的版本,包括:
 	- 使用 File 类的 listFiles() 方法
 	- 在 Java 7 及更高版本中使用 DirectoryStream
 	- 在 Java 8 及更高版本中使用静态 Files.list() 方法
 	- 在 Java 8 及更高版本中使用 walk() 方法
本编程教程将演示如何利用上述每种技术在 Java 中导航目录结构。
Java 中的 File listFiles() 方法。
listFiles() 是 java.io.File 类的一个实例方法。要使用它,开发人员需要做的就是通过提供构造函数的路径来实例化一个新的 File 对象,然后在其上调用 listFiles()。listFiles() 返回一个 File 对象数组,然后程序员可以迭代这些对象以获取有关单个文件的更多信息和/或对它们执行操作。下面是一个基本示例,其中列出了 Windows“C:\My Documents”文件夹中的所有文件和目录:
package com.developer;
import java.io.File;
public class ListFilesExample {
  public static void main(String[] args) {
    // Store the name of files and directories
    // in an array of Files.
    // Don't forget to escape the backslash character!
    File[] files = new File("C:\\My Documents").listFiles();
    
    // Traverse through the files array
    for (File file : files) {
      // If a subdirectory is found,
      // print the name of the subdirectory
      if (file.isDirectory()) {
        System.out.println("Directory: " + file.getName());
      }
      else {
        // Print the file name
        System.out.println("File: " + file.getName());
      }
    }
  }
}
以下是找到的目录和文件的部分列表:
Directory: AAMS
Directory: Addictive Drums
Directory: Angular
Directory: angular-starter
Directory: Any Video Converter
Directory: articles
File: Avatar - House Of Eternal Hunt - transposed.tg
File: Avatar - House Of Eternal Hunt.tg
File: Avatar - Legend Of The King.tg
Directory: bgfx
Java 中的递归目录遍历
由于我们可以测试目录,我们可以将 for 循环移动到一个单独的方法中,我们可以递归调用该方法以列出子目录的文件以及提供给我们方法的文件,如下面的 Java 代码示例所示:
package com.developer;
import java.io.File;
public class RecursiveListFilesExample {
	
  public static void main(String[] args) {
    listFilesInDirectory(new File("C:\\My Documents"));
  }
  
  private static void listFilesInDirectory(File dirPath) {
    File filesList[] = dirPath.listFiles();
    
    // Traverse through the files array
    for (File file : filesList) {
      // If a sub directory is found,
      // print the name of the sub directory
      if (file.isDirectory()) {
        System.out.println("Directory: " + file.getName());
        listFilesInDirectory(file);
      }
      else {
        // Print the file name present in given path
        System.out.println("File: " + file.getName());
      }
    }
  }
}
我们可以在程序输出中看到,它现在也列出了子目录的文件:
Directory: AAMS
File: AAMS V3 Manual.pdf
File: AAMS V4 Setup.exe
File: AAMS.xml
File: Licence.txt
File: Version.txt
Directory: Addictive Drums
Directory: Settings
File: MidifileDatabaseCache.dat
File: Recent.dat
使用 DirectoryStream 通过 Java 循环访问文件
Java 7引入了listFiles()的替代方案,称为DirectoryStream。它与 for-each 结构配合得很好,允许我们迭代目录的内容,而不是一次读取所有内容。
下面的示例代码显示了如何在一种方法中使用 Java 的 DirectoryStream 来列出目录的文件:
public Set listFilesUsingDirectoryStream(String dir) throws IOException {
  Set fileSet = new HashSet<>();
  try (DirectoryStream stream = Files.newDirectoryStream(Paths.get(dir))) {
    for (Path path : stream) {
      if (!Files.isDirectory(path)) {
        fileSet.add(path.getFileName()
          .toString());
      }
    }
  }
  return fileSet;
}
上面,我们让 Java 通过 try-with-resources 构造来处理 DirectoryStream 资源的关闭。我们可以采用静态 Files.isDirectory(path) 方法来过滤掉目录并返回文件夹中的一组文件。
使用静态 Files.list() 方法
Java 8在java.nio.file.Files中引入了一个新的list()方法。list 方法返回目录中延迟填充的条目流。因此,处理大型文件夹更有效。下面是一个返回一组文件名的方法:
public Set listFilesUsingFilesList(String dir) throws IOException {
  try (Stream stream = Files.list(Paths.get(dir))) {
    return stream
      .filter(file -> !Files.isDirectory(file))
      .map(Path::getFileName)
      .map(Path::toString)
      .collect(Collectors.toSet());
  }
}
尽管上面的代码可能看起来类似于 listFiles(),但它在开发人员获取每个文件的路径的方式上有所不同。
同样,我们使用 try-with-resources 构造创建了流,以确保在读取流后关闭目录资源。
如何在 Java 中浏览目录内容
walk() 方法通过以深度优先的方式从给定的起始文件/目录开始遍历文件树来返回 Stream(这意味着它以最大深度的文件/目录开始)。以下程序在“C:\My Documents”下打印完整文件树的完整文件路径:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
class FilesWalkExample {
  public static void main(String[] args)
    throws IOException {
  
    // Create a try-catch block and
    // provide the directory path of local machine
    try (Stream filepath = Files.walk(Paths.get("C:\\My Documents"))) {
      // Print the entire path of directories and files
      filepath.forEach(System.out::println);
    }
    // Throw an if directory doesn't exists 
    catch (IOException e) {
      throw new IOException("Directory not found!");
    }
  }
}
输出的前几行确认文件遍历开始了最深的深度:
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy\page1.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy\page2.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy\page3.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\readOnlyPage.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\rectangles.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\Redirect.aspx
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\Redirect.aspx.cs
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\resultPage.html
关于 Java 中目录导航的最终想法
Java 提供了几种遍历目录的方法,具体取决于您使用的版本。虽然我们介绍了主要的目录,但在 Java 中还有其他导航目录的方法,特别是自从 Java 8 中引入了 Stream API 以来。
 
来源:techrepublic.com/article/java-directory-navigation/