Java NIO files

Java NIO files

java.nio.file.Files类提供了许多操作文件的方法,它们往往和Path类合作使用。

1.Files.exits()

Files#exits()方法检查一个Path是否存在于当前的文件系统中。假如我们直接使用Path实例的相关方法,那么一个不存在的文件可能会被创建,如果我们想避免这种情况的发生,那么可以先使用Files#extis()来进行一下检查。

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

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

显然,exits()方法有两个参数,第一个是要检查的path,第二个是exits()方法的选项数组。如LinkOption.NOFOLLOW_LINKS代表不允许跟随文件系统中的符号链接来确定路径是否存在。

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

通过上面的示例一眼就可以看出这个方法是干嘛用的,另外就是注意一下通过抛出异常来对不同的情况进行处理。

注:假如父目录不存在,可能抛出IOException异常。

3.Files.copy()

Files#copy()方法将文件从一个path复制到另一个。

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

功能太明显了。如果目标文件已存在,会抛出FileAlreadyExistsException,如果试图将文件复制到不存在的目录,会抛出IOException

但也可以要求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();
}

在copy方法的参数列表中加上这个StandardCopyOption.REPLACE_EXISTING,可以在目标文件存在时强制覆盖。

4.FIles.move()

Files#move()方法将文件从一个path移动到另一个path。同时可以设定目标的文件名,也就是说不仅可以实现移动功能,也可以实现重命名或移动+重命名。

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

功能显而易见,StandardCopyOption.REPLACE_EXISTING参数的意义和copy方法中的一样。

5.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();
}

6.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。表示文件遍历将继续,但不再访问此目录内的文件。

下面是一个通过walkFileTree()方法寻找名字为README.txt的文件的示例。注意这里的FileVisitor是继承SimpleFileVisitor的,不过重写了visitFile方法。

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

下面是一个通过walkFileTree()方法删除名字为README.txt的文件的示例。注意这里的FileVisitor是继承SimpleFileVisitor的,不过重写了visitFile方法和postVisitDirectory方法。

Files#delete()方法仅在目录为空时删除目录,但下面的代码可以递归删除。

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类中还有许多其他方法,可以自己去看API。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值