Path

jdk7 引入了 Path 和 Paths 类

  • Path 用来表示文件路径
  • Paths 是工具类,用来获取 Path 实例

    1. Path source = Paths.get("1.txt"); // 相对路径 使用 user.dir 环境变量来定位 1.txt
    2. Path source = Paths.get("d:\\1.txt"); // 绝对路径 代表了 d:\1.txt
    3. Path source = Paths.get("d:/1.txt"); // 绝对路径 同样代表了 d:\1.txt
    4. Path projects = Paths.get("d:\\data", "projects"); // 代表了 d:\data\projects
  • . 代表了当前路径

  • .. 代表了上一级路径

例如目录结构如下
d:
|- data
|- projects
|- a
|- b
代码

  1. Path path = Paths.get("d:\\data\\projects\\a\\..\\b");
  2. System.out.println(path);
  3. System.out.println(path.normalize()); // 正常化路径

会输出
d:\data\projects\a..\b
d:\data\projects\b

Files

检查文件是否存在

  1. Path path = Paths.get("helloword/data.txt");
  2. System.out.println(Files.exists(path));

创建一级目录

  1. Path path = Paths.get("helloword/d1");
  2. Files.createDirectory(path);
  • 如果目录已存在,会抛异常 FileAlreadyExistsException
  • 不能一次创建多级目录,否则会抛异常 NoSuchFileException

创建多级目录用

  1. Path path = Paths.get("helloword/d1/d2");
  2. Files.createDirectories(path);

拷贝文件

  1. Path source = Paths.get("helloword/data.txt");
  2. Path target = Paths.get("helloword/target.txt");
  3. Files.copy(source, target);
  • 如果文件已存在,会抛异常 FileAlreadyExistsException

如果希望用 source 覆盖掉 target,需要用 StandardCopyOption 来控制

  1. Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

移动文件

  1. Path source = Paths.get("helloword/data.txt");
  2. Path target = Paths.get("helloword/data.txt");
  3. Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
  • StandardCopyOption.ATOMIC_MOVE 保证文件移动的原子性

删除文件

  1. Path target = Paths.get("helloword/target.txt");
  2. Files.delete(target);
  • 如果文件不存在,会抛异常 NoSuchFileException

删除目录

  1. Path target = Paths.get("helloword/d1");
  2. Files.delete(target);
  • 如果目录还有内容,会抛异常 DirectoryNotEmptyException

遍历目录文件 walkFileTree

  1. public static void main(String[] args) throws IOException {
  2. Path path = Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91");
  3. AtomicInteger dirCount = new AtomicInteger();
  4. AtomicInteger fileCount = new AtomicInteger();
  5. Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
  6. @Override
  7. public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
  8. throws IOException {
  9. System.out.println(dir);
  10. dirCount.incrementAndGet();
  11. return super.preVisitDirectory(dir, attrs);
  12. }
  13. @Override
  14. public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
  15. throws IOException {
  16. System.out.println(file);
  17. fileCount.incrementAndGet();
  18. return super.visitFile(file, attrs);
  19. }
  20. });
  21. System.out.println(dirCount); // 133
  22. System.out.println(fileCount); // 1479
  23. }

统计 jar 的数目

  1. Path path = Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91");
  2. AtomicInteger fileCount = new AtomicInteger();
  3. Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
  4. @Override
  5. public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
  6. throws IOException {
  7. if (file.toFile().getName().endsWith(".jar")) {
  8. fileCount.incrementAndGet();
  9. }
  10. return super.visitFile(file, attrs);
  11. }
  12. });
  13. System.out.println(fileCount); // 724

删除多级目录

  1. Path path = Paths.get("d:\\a");
  2. Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
  3. @Override
  4. public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
  5. throws IOException {
  6. Files.delete(file);
  7. return super.visitFile(file, attrs);
  8. }
  9. @Override
  10. public FileVisitResult postVisitDirectory(Path dir, IOException exc)
  11. throws IOException {
  12. Files.delete(dir);
  13. return super.postVisitDirectory(dir, exc);
  14. }
  15. });

⚠️ 删除很危险

删除是危险操作,确保要递归删除的文件夹没有重要内容

拷贝多级目录

  1. long start = System.currentTimeMillis();
  2. String source = "D:\\Snipaste-1.16.2-x64";
  3. String target = "D:\\Snipaste-1.16.2-x64aaa";
  4. Files.walk(Paths.get(source)).forEach(path -> {
  5. try {
  6. String targetName = path.toString().replace(source, target);
  7. // 是目录
  8. if (Files.isDirectory(path)) {
  9. Files.createDirectory(Paths.get(targetName));
  10. }
  11. // 是普通文件
  12. else if (Files.isRegularFile(path)) {
  13. Files.copy(path, Paths.get(targetName));
  14. }
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. }
  18. });
  19. long end = System.currentTimeMillis();
  20. System.out.println(end - start);