(nio)Files 详细相关操作和演示代码,如删除、拷贝(多级)文件目录等

Files

检查文件是否存在

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

创建一级目录

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

创建多级目录用

Path path = Paths.get("helloword/d1/d2");  // 即使d1目录不能存在也会创建出来
Files.createDirectories(path);

拷贝文件

Path source = Paths.get("helloword/data.txt");
Path target = Paths.get("helloword/target.txt");

Files.copy(source, target);  // 从source 拷贝到 target
  • 如果文件已存在,会抛异常 FileAlreadyExistsException

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

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

要拷贝文件的话,就用这个这个 copy或是 transferTo,这两个方法都是效率比较高的

移动文件

Path source = Paths.get("helloword/data.txt");
Path target = Paths.get("helloword/data.txt");

Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
  • StandardCopyOption.ATOMIC_MOVE 保证文件移动的原子性

删除文件

Path target = Paths.get("helloword/target.txt");

Files.delete(target);
  • 如果文件不存在,会抛异常 NoSuchFileException

删除目录(只能删除一个空目录)

Path target = Paths.get("helloword/d1");

Files.delete(target);
  • 如果目录还有内容,会抛异常 DirectoryNotEmptyException

遍历目录文件

public static void main(String[] args) throws IOException {
    
    
    Path path = Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91");   // 遍历的其实文件
    AtomicInteger dirCount = new AtomicInteger();
    AtomicInteger fileCount = new AtomicInteger();
    //                       这里的代码模式用到了访问者模式,你要做的操作就通过访问者来加入你的逻辑即可
    Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
    
    
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) 
            throws IOException {
    
    
            System.out.println(dir);
            dirCount.incrementAndGet();  // +1   
            // 注意这里是匿名内部类里的,所以不能用 在外面的 int 来 ++,匿名类要应用外部局部变量实质是个常量来的,是不能改变它的值的
            // 要用要用累加器来计算
            return super.preVisitDirectory(dir, attrs);
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
            throws IOException {
    
    
            System.out.println(file);
            fileCount.incrementAndGet();
            return super.visitFile(file, attrs);
        }
    });
    System.out.println(dirCount); // 133
    System.out.println(fileCount); // 1479
}

统计 jar 的数目

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

删除多级目录

Path path = Paths.get("d:\\a");
Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
    
    
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
        throws IOException {
    
    
        Files.delete(file);
        return super.visitFile(file, attrs);
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) 
        throws IOException {
    
    
        Files.delete(dir);
        return super.postVisitDirectory(dir, exc);
    }
});

⚠️ 删除很危险

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

拷贝多级目录

public static void main(String[] args) throws IOException {
    
    

        long start = System.currentTimeMillis();
        String source = "F:\\aaaa";     // 被拷贝的原始目录
        String target = "F:\\bbbb";
        //          起始路径 Paths.get(source)返回的是一个Stream流,所以我们可以用Stream流对应的一些 api 来进行操作
        //                                    path : 就是遍历到的文件目录
        Files.walk(Paths.get(source)).forEach(path -> {
    
    
            try {
    
    

                System.out.println( " 遍历到的 =====》" +  path );

                // targerName就是最终要操作的目录
                /*
                 source 目录被替换成target目录,比如 source = F:\\aaaa, target = "F:\\bbbb"
                 那么再拷贝 D:\\aaaa\\bb.txt时,就需要替换成 D:\\bbbb\\bb.txt,即source部分被替换成target
                 */
                String targetName = path.toString().replace(source, target);
                System.out.println( "替换后的 ------>" +  targetName );
                // 是目录
                if (Files.isDirectory(path)) {
    
    
                    Files.createDirectory(Paths.get(targetName));
                }
                // 是普通文件
                else if (Files.isRegularFile(path)) {
    
    
                    // 把
                    Files.copy(path, Paths.get(targetName));
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        });
        long end = System.currentTimeMillis();
        System.out.println( "花时 : " + (end - start)+ "ms" );
    }
}

运行时输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-36vxpC0K-1673630241801)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TMVDfrZw-1673630255597)(../../RunningYuBlog/source/images/image-20230114011523888.png)]

拷贝出了bbbb
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0aZTxK3-1673630241803)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y0fAIUOE-1673630263761)(../../RunningYuBlog/source/images/image-20230114011547604.png)]

猜你喜欢

转载自blog.csdn.net/QRLYLETITBE/article/details/128681657
今日推荐