持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天, 点击查看活动详情

Files 是Java1.7 在 nio 中新增的专门用于处理文件和目录的工具类。 Files Path 配合可以很方便的完成对文件/目录的创建、读取、修改、删除等操作。

二、常用方法介绍

2.1 Files.exits()

boolean exists(Path path, LinkOption... options)

描述 :方法检查一个路径是否存在于当前的文件系统中。

  • Path :传入的文件路径。 必须
  • LinkOption: exits() 方法的选项数组。如 LinkOption.NOFOLLOW_LINKS 代表不允许跟随文件系统中的符号链接来确定路径是否存在。 非必须
  • Path path = Paths.get("D:\\path_test\\demo");
    boolean exists = Files.exists(path);
    System.out.println(exists);
    

    2.2 Files.createDirectory()

    createDirectory(Path dir, FileAttribute<?>... attrs)

    描述:此方法使用给定的路径创建目录,如果创建目录成功,它将返回创建的目录的路径。

  • Path :需要创建的文件路径。必须
  • FileAttribute:是在创建不存在的目录时自动设置的可选参数,它返回创建的目录的路径。非必须
  • 如果目录已经存在,那么它会抛出nio.file.FileAlreadyExistsException。
  • 不能一次创建多级目录,否则会抛异常 NoSuchFileException
  • Path path = Paths.get("D:\\path_test\\demo2");
    Files.createDirectories(path);
    

    2.3 Files.createDirectories()

    createDirectories(Path dir, FileAttribute<?>... attrs)

    描述:此方法通过首先创建所有不存在的父目录来使用给定路径创建目录。如果由于目录已存在而无法创建该目录,则此方法不会引发异常。

    该方法用来创建多级目录。

    Path path = Paths.get("D:\\path_test\\demo3\\a\\b");
    Files.createDirectories(path);
    

    2.4 Files.copy()

    long copy(InputStream in, Path target, CopyOption... options)

    描述:此方法将指定输入流中的所有字节复制到指定目标文件,并返回读取或写入的字节数作为长值。

  • 将InputStream中的数据复制到目标文件
  • InputStream inputStream = new FileInputStream("D:\\path_test\\demo\\first_input.txt");
    Path targetPath = Paths.get("D:\\path_test\\demo3\\first_copy2.txt");
    long size = Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING);
    System.out.println(size);
    
  • 默认情况,如果目标文件已经存在或是一个符号链接,则复制失败;
  • 指定了REPLACE_EXISTING的情况,如果目标文件已经存在,那么只要它不是一个非空目录(例如它是一个空目录,或者是一个符号链接),它就会被替换。截止到JDK1.8,options只支持REPLACE_EXISTING
  • long copy(Path source, OutputStream out)

    描述:此方法将指定源文件中的所有字节复制到给定的输出流,并返回读取或写入的字节数作为长值。

  • 将本地文件中的内容复制到OutputStream
  • Path path = Paths.get("D:\\path_test\\demo\\first_copy.txt");
    OutputStream outputStream = new FileOutputStream("D:\\path_test\\demo\\first_output.txt");
    long size = Files.copy(path, outputStream);
    System.out.println(size);
    
  • 当发生异常的时候,由于输出了可能已经获取到了一部分内容,所以输出流此时的内容可能很奇怪,应该直接关闭。
  • 如果输出流是Flushable的实现类的实例,在执行完方法以后应该调用flush方法以刷新缓存。
  • Path copy(Path source, Path target, CopyOption... options)

    描述:此方法将给定的源文件复制到指定的目标文件,并返回目标文件的路径。

  • 将文件first_copy.txt复制到文件first_copy2.txt
  • Path path = Paths.get("D:\\path_test\\demo3\\first_copy.txt");
    Path targetPath = Paths.get("D:\\path_test\\demo3\\first_copy2.txt");
    Path copy = Files.copy(path, targetPath);
    System.out.println(copy);
    
  • 在默认情况下,如果目标文件已经存在,或者是一个符号链接,那么复制失败;
  • options参数

    参数说明
    REPLACE_EXISTING如果目标文件已经存在,那么只要它不是一个非空目录,它就会被替换。
    COPY_ATTRIBUTES把source的文件属性复制给target,被复制的属性取决于平台和文件系统,但是至少在source和target都支持的情况下,会复制最新修改时间。
    NOFOLLOW_LINKS直接复制符号链接自身,而不是符号链接指向的目的地。可被复制的属性也会被复制,也就是说NOFOLLOW_LINKS的情况下配置COPY_ATTRIBUTES是没有意义的。

    2.5 Files.move()

    move(Path source, Path target, CopyOption... options)

    描述:此方法将源文件移动或重命名为目标文件,并返回目标文件的路径。

    Path sourcePath = Paths.get("D:\\path_test\\demo\\first_copy.txt");
    Path targetPath = Paths.get("D:\\path_test\\demo3\\first_copy2.txt");
    Path move = Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
    System.out.println(move);
    

    options参数

    参数说明
    REPLACE_EXISTING如果目标文件存在,则如果它不是非空目录,则替换它。
    ATOMIC_MOVE表示移动文件作为原子文件系统操作执行,所有其他选项都被忽略。
  • 如果目标文件存在但由于未指定REPLACE_EXISTING选项而无法替换,则此方法将引发FileAleadyExistsException
  • 如果指定了REPlACE_EXISTING选项,则此方法将引发DirectoryNotEmptyException但无法替换该文件,因为它是一个非空目录。
  • 2.6 Files.delete()

    void delete(Path path)

    描述:删除一个文件或文件夹。

    Path path = Paths.get("D:\\path_test\\demo");
    //如果path指定到一个目录,并且目标不为空时会抛出异常
    Files.delete(path);
    

    如果目标存在,并且是文件或者空的文件夹,就删除文件;如果目标不存在,或者目标是非空的文件夹,就会抛出异常。

    2.7 Files.walkFileTree()

    描述Files.walkFileTree()方法可以递归遍历目录树。它使用一个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;
    

    Files.walkFileTree()方法需要一个FileVisitor的实现类作为参数,实现FileVisitor接口就需要实现上述方法。

    如果不想做特殊实现或者只想实现一部分,可以继承SimpleFileVisitor类,它其中有对FileVisitor的方法的默认实现。

    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;
    

    这些方法在遍历的不同时间被调用

  • preVisitDirectory()方法在访问任何目录前被调用。
  • postVisitDirectory()方法在访问任何目录后被调用。
  • visitFile()方法在访问任何文件时被调用。
  • visitFileFailed()在访问任何文件失败时被调用。(比如没权限)
  • 每个方法返回一个FileVisitResult枚举,这些返回指决定了遍历如何进行。

    参数说明
    CONTINUE表示遍历将继续正常进行
    TERMINATE表示文件遍历将终止
    SKIP_SIBLINGS表示文件遍历将继续,但不在访问此文件/目录的同级文件/目录
    SKIP_SUBTREE表示文件遍历将继续,但不再访问此目录内的文件