www.zhblog.net

Java NIO Files 的常用方法

Java NIO Files类(java.nio.file.Files)提供了几种操作文件的方法,这里介绍一些最常用的方法。 

java.nio.file.Files类可与java.nio.file.Path实例一起使用,因此在使用Files类之前,需要了解Path类。


1.Files.exists()

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

如果你打算创建一个新目录,则首先要创建相应的Path实例,然后再创建目录。

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

一个Java Files.exists()示例:

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



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


创建一个Path实例,该实例指向我们要检查是否存在的路径。


2.Files.createDirectory()

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

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。如果还有其它错误,可能会引发IOException。例如,如果所需的新目录的父目录不存在,则可能引发IOException。


3.Files.copy()

Files.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。如果发生其他错误,将抛出IOException。例如,如果复制文件的目录不存在,则将抛出IOException。


4.覆盖现有文件

可以强制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()方法覆盖现有文件。


5.Files.move()

Java NIO Files类还包含一个用于将文件从一个路径移动到另一路径的函数。移动文件与重命名相同,不同之处在于移动文件既可以将文件移动到另一个目录,又可以在同一操作中更改其名称。java.io.File类也可以使用自己的namedTo()方法来做到这一点。

示例:

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选项,或者要移动的文件不存在,等等。


6.Files.delete()

Files.delete()方法可以删除文件或目录。示例:

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



try {

    Files.delete(path);

} catch (IOException e) {

    //deleting file failed

    e.printStackTrace();

}


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


7.Files.walkFileTree()

Files.walkFileTree()方法包含用于递归遍历目录树的功能。 walkFileTree()方法将Path实例和FileVisitor作为参数,Path实例指向要遍历的目录。在遍历期间将调用FileVisitor。

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。


8.搜索文件

这是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();

}



9.递归删除目录

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();

}



java.nio.file.Files类还包含许多其它有用的方法,例如用于创建符号链接,确定文件大小,设置文件权限等的功能。有关更多信息,请查阅JavaDoc中的java.nio.file.Files类。


 

展开阅读全文

评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 心情