当前位置: 首页 > 教程 > Java NIO >

Java NIO Files类

精华
小牛编辑
97浏览
2023-03-14

Java NIO Files类(java.nio.file.Files)提供了几种在文件系统中操作文件的方法。本Java NIOFiles教程将介绍这些方法中最常用的方法。本Files类包含了许多方法,所以检查的JavaDoc也一样,如果你需要的是不是这里所描述的方法。该Files班只可能有一个方法,它仍然。

在java.nio.file.Files类的工作与java.nio.file.Path 实例,所以你需要了解的Path类,然后才能与工作Files 类。

1 Files.exists()方法

Files.exists()方法检查给定Path文件系统中是否存在给定文件。

可以创建Path文件系统中不存在的实例。例如,如果您打算创建一个新目录,则首先要创建相应的Path实例,然后再创建目录。

由于Path实例可能指向文件系统中存在的路径,也可能不指向文件系统中存在的路径,因此您可以使用该Files.exists()方法确定它们是否存在(以防需要检查)。

这是一个JavaFiles.exists()示例:

Path path = Paths.get("data/logging.properties");

boolean pathExists =
        Files.exists(path,
            new LinkOption[]{ LinkOption.NOFOLLOW_LINKS});

此示例首先创建一个Path实例,该实例指向我们要检查的路径是否存在。其次,该示例Files.exists()以Path实例作为第一个参数调用该方法。

注意方法的第二个参数Files.exists()。此参数是一组选项,这些选项会影响Files.exists()确定路径是否存在的方式。在上面的示例中,数组包含LinkOption.NOFOLLOW_LINKS,表示该Files.exists() 方法不应遵循文件系统中的符号链接来确定路径是否存在。

2 Files.createDirectory()方法

该Files.createDirectory()方法从Path实例创建一个新目录。这是一个JavaFiles.createDirectory()示例:

Path path = Paths.get("data/subdir");

try {
    Path newDir = Files.createDirectory(path);
} catch(FileAlreadyExistsException e){
    // the directory already exists.
} catch (IOException e) {
    //something else went wrong
    e.printStackTrace();
}

第一行创建Path代表要创建目录的实例。在try-catch块内部,Files.createDirectory()使用路径作为参数调用该方法。如果创建目录成功,将Path返回一个实例,该实例指向新创建的路径。

如果目录已经存在,java.nio.file.FileAlreadyExistsException将抛出a。如果发生其他问题,IOException可能会引发错误。例如,如果所需的新目录的父目录不存在,则IOException可能抛出。父目录是您要在其中创建新目录的目录。因此,这意味着新目录的父目录。

3 Files.copy()方法

该Files.copy()方法将文件从一个路径复制到另一路径。这是一个Java NIOFiles.copy() 示例:

Path sourcePath      = Paths.get("data/logging.properties");
Path destinationPath = Paths.get("data/logging-copy.properties");

try {
    Files.copy(sourcePath, destinationPath);
} catch(FileAlreadyExistsException e) {
    //destination file already exists
} catch (IOException e) {
    //something else went wrong
    e.printStackTrace();
}

首先,该示例创建一个源Path实例和目标实例。然后示例调用 Files.copy(),将两个Path实例作为参数传递。这将导致源路径引用的文件被复制到目标路径引用的文件。

如果目标文件已经存在,java.nio.file.FileAlreadyExistsException则抛出a。如果其他地方出了问题,IOException将抛出。例如,如果不存在IOException将文件复制到的目录,则将抛出。

3.1 覆盖现有文件

可以强制Files.copy()覆盖现有文件。这是显示如何使用覆盖现有文件的示例Files.copy():

Path sourcePath      = Paths.get("data/logging.properties");
Path destinationPath = Paths.get("data/logging-copy.properties");

try {
    Files.copy(sourcePath, destinationPath,
            StandardCopyOption.REPLACE_EXISTING);
} catch(FileAlreadyExistsException e) {
    //destination file already exists
} catch (IOException e) {
    //something else went wrong
    e.printStackTrace();
}

注意该Files.copy()方法的第三个参数。copy() 如果目标文件已经存在,则此参数指示方法覆盖现有文件。

4 Files.move()方法

Java NIOFiles类还包含一个用于将文件从一个路径移动到另一路径的函数。移动文件与重命名相同,只是移动文件既可以将文件移动到另一个目录,又可以在同一操作中更改其名称。是的,java.io.File该类也可以使用其renameTo() 方法执行此操作,但是现在您在java.nio.file.Files类中也具有文件移动功能。

这是一个JavaFiles.move()示例:

Path sourcePath      = Paths.get("data/logging-copy.properties");
Path destinationPath = Paths.get("data/subdir/logging-moved.properties");

try {
    Files.move(sourcePath, destinationPath,
            StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
    //moving file failed.
    e.printStackTrace();
}

首先,创建源路径和目标路径。源路径指向要移动的文件,目标路径指向应将文件移动到的位置。然后Files.move()调用该方法。这导致文件被移动。

请注意传递给的第三个参数Files.move()。此参数告诉Files.move()方法覆盖目标路径上的任何现有文件。该参数实际上是可选的。

如果移动文件失败Files.move(),IOException则 该方法可能抛出。例如,如果目标路径上已经存在文件,而您没有StandardCopyOption.REPLACE_EXISTING 选择该选项,或者要移动的文件不存在,等等。

5 Files.delete()方法

该Files.delete()方法可以删除文件或目录。这是一个JavaFiles.delete()示例:

Path path = Paths.get("data/subdir/logging-moved.properties");

try {
    Files.delete(path);
} catch (IOException e) {
    //deleting file failed
    e.printStackTrace();
}

首先Path创建指向要删除文件的指向。其次,该Files.delete() 方法被调用。如果由于Files.delete()某种原因未能删除文件(例如,文件或目录不存在),IOException则抛出。

6 Files.walkFileTree()方法

该Files.walkFileTree()方法包含用于递归遍历目录树的功能。该walkFileTree()方法将Path实例和aFileVisitor作为参数。该Path实例指向您要遍历的目录。该FileVisitor traversion时被调用。

在解释遍历如何工作之前,首先是以下FileVisitor接口:

public interface FileVisitor {

    public FileVisitResult preVisitDirectory(
        Path dir, BasicFileAttributes attrs) throws IOException;

    public FileVisitResult visitFile(
        Path file, BasicFileAttributes attrs) throws IOException;

    public FileVisitResult visitFileFailed(
        Path file, IOException exc) throws IOException;

    public FileVisitResult postVisitDirectory(
        Path dir, IOException exc) throws IOException {

}

您必须自己实现FileVisitor接口,并将实现的实例传递给walkFileTree()方法。FileVisitor在遍历目录期间,将在不同时间调用实现的每种方法。如果不需要使用所有这些方法,则可以扩展SimpleFileVisitor该类,该类包含FileVisitor接口中所有方法的默认实现。

这是一个walkFileTree()例子:

Files.walkFileTree(path, new FileVisitor<Path>() {
  @Override
  public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
    System.out.println("pre visit dir:" + dir);
    return FileVisitResult.CONTINUE;
  }

  @Override
  public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
    System.out.println("visit file: " + file);
    return FileVisitResult.CONTINUE;
  }

  @Override
  public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
    System.out.println("visit file failed: " + file);
    return FileVisitResult.CONTINUE;
  }

  @Override
  public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
    System.out.println("post visit directory: " + dir);
    return FileVisitResult.CONTINUE;
  }
});

FileVisitor遍历期间 ,实现中的每个方法都会在不同时间调用:

preVisitDirectory()在访问任何目录之前都会调用 该方法。postVisitDirectory()访问目录后立即调用该 方法。

visitFile()在文件遍历期间访问的每个文件都会调用 该方法。它不用于目录-仅用于文件。visitFileFailed()如果访问文件失败,则调用该方法。例如,如果您没有正确的权限,或者发生其他错误。

四个方法均返回一个FileVisitResult枚举实例。该FileVisitResult 枚举包含以下四个选项:

  • CONTINUE
  • TERMINATE
  • SKIP_SIBLINGS
  • SKIP_SUBTREE

通过返回这些值之一,被调用的方法可以决定如何继续文件遍历。

CONTINUE 表示文件漫游应继续正常进行。

TERMINATE 表示文件漫游应立即终止。

SKIP_SIBLINGS 表示应该继续执行文件漫游,但不能访问此文件或目录的任何同级文件。

SKIP_SUBTREE表示应该继续执行文件遍历,但无需访问此目录中的条目。如果从返回,则此值仅具有功能preVisitDirectory()。如果从任何其他方法返回,它将被解释为CONTINUE。

6.1 搜索文件

这是一个walkFileTree()扩展SimpleFileVisitor名为的文件 README.txt:

Path rootPath = Paths.get("data");
String fileToFind = File.separator + "README.txt";

try {
  Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() {
    
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      String fileString = file.toAbsolutePath().toString();
      //System.out.println("pathString = " + fileString);

      if(fileString.endsWith(fileToFind)){
        System.out.println("file found at path: " + file.toAbsolutePath());
        return FileVisitResult.TERMINATE;
      }
      return FileVisitResult.CONTINUE;
    }
  });
} catch(IOException e){
    e.printStackTrace();
}

6.2 递归删除目录

该Files.walkFileTree()还可以用来删除一个目录,它里面的所有文件和子目录。该Files.delete()方法仅在目录为空时将其删除。通过遍历所有目录并删除visitFile()每个目录中的所有文件(在里面),然后删除目录本身(在里面postVisitDirectory()),您可以删除包含所有子目录和文件的目录。这是递归目录删除示例:

Path rootPath = Paths.get("data/to-delete");

try {
  Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      System.out.println("delete file: " + file.toString());
      Files.delete(file);
      return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
      Files.delete(dir);
      System.out.println("delete dir: " + dir.toString());
      return FileVisitResult.CONTINUE;
    }
  });
} catch(IOException e){
  e.printStackTrace();
}

7 Files类中的其他方法

本java.nio.file.Files类包含用于创建符号链接,确定文件的大小,设置文件权限等,检查出的的JavaDoc其他许多有用的功能,如功能 java.nio.file.Files类有关这些方法的详细信息。