首頁 >Java >java教程 >如何在Java中刪除檔案或資料夾?

如何在Java中刪除檔案或資料夾?

王林
王林轉載
2023-04-19 14:46:132922瀏覽

    刪除檔案或資料夾的四個基礎方法

    下面的四個方法都可以刪除檔案或資料夾。

    它們的共同點是:

    當資料夾中包含子檔案的時候都會刪除失敗,也就是說這四個方法只能刪除空資料夾。

    //delete是立即執行刪除,而deleteOnExit是程式退出虛擬機器時才會刪除。

    File類別的delete()

    • #File類別的deleteOnExit():當虛擬機器終止時,刪除File物件表示的檔案或目錄,如果表示的是目錄,則需要保證目錄是空的,否則無法刪除,無回傳值。

    • Files.delete(Path path):刪除位於作為參數傳遞的路徑上的檔案。對於其他檔案系統操作,此方法可能不是原子的。如果檔案是符號鏈接,則將刪除符號鏈接本身而不是鏈接的最終目標。如果檔案是目錄,則此方法僅在目錄為空時才刪除該檔案。

    Files.deleteIfExists(Path path)

    要注意的是:

    #傳統IO中的File類別和NIO中的Path類別既可以代表文件,也可以代表資料夾。

    上面的四個方法簡單對比
    File類別的deleteOnExit()傳統IO,這是個坑,避免使用void不能,但不存在就不會去執行刪除 #不能(返回void)Files.delete(Path path)NIO,推薦使用void
    - #說明 #成功的回傳值 #是否能判別資料夾不存在導致失敗 是否能判別資料夾不為空導致失敗
    #File類別的delete( ) 傳統IO true 不能(返回false) 不能(返回false)
    NoSuchFileException

    DirectoryNotEmptyException

    Files.deleteIfExists(Path path)NIOtruefalseDirectoryNotEmptyException
    //删除暂存的pdf
    File file =new File(pdfFilename);
    file.delete();
    
    Path path4 = Paths.get(pdfFilename);
    Files.delete(path4);
    --File.delete()Files.delete(Path path) JDKJDK1.0JDK1.7#來源java.io.File物件的實例方法java.nio.file.Files類別的靜態方法參數#無參考java.nio.file.Path回傳值booleanvoid#異常宣告無宣告宣告拋出java.io.IOException檔案不存在不拋出例外,回傳false拋java.nio. file.NoSuchFileException刪除非空目錄#無法刪除,傳回false無法刪除,拋java.nio.file.DirectoryNotEmptyException
    File.delete()和Files.delete(Path path)比較區別:
    #########刪除被佔用檔案######無法刪除,傳回false#######無法刪除,拋java.nio.file.FileSystemException########## ###其他原因檔案無法刪除######不拋例外,回傳false######拋java.io.IOException的具體子類別############

    如何删除整个目录或者目录中的部分文件

    先造数据

    private  void createMoreFiles() throws IOException {
       Files.createDirectories(Paths.get("D:\data\test1\test2\test3\test4\test5\"));
       Files.write(Paths.get("D:\data\test1\test2\test2.log"), "hello".getBytes());
       Files.write(Paths.get("D:\data\test1\test2\test3\test3.log"), "hello".getBytes());
    }
    walkFileTree与FileVisitor

    使用walkFileTree方法遍历整个文件目录树,使用FileVisitor处理遍历出来的每一项文件或文件夹

    • FileVisitor的visitFile方法用来处理遍历结果中的“文件”,所以我们可以在这个方法里面删除文件

    • FileVisitor的postVisitDirectory方法,注意方法中的“post”表示“后去做……”的意思,所以用来文件都处理完成之后再去处理文件夹,所以使用这个方法删除文件夹就可以有效避免文件夹内容不为空的异常,因为

    在去删除文件夹之前,该文件夹里面的文件已经被删除了。

    @Test
    void testDeleteFileDir5() throws IOException {
       createMoreFiles();
       Path path = Paths.get("D:\data\test1\test2");
    
       Files.walkFileTree(path,
          new SimpleFileVisitor<Path>() {
             // 先去遍历删除文件
             @Override
             public FileVisitResult visitFile(Path file,
                                      BasicFileAttributes attrs) throws IOException {
                Files.delete(file);
                System.out.printf("文件被删除 : %s%n", file);
                return FileVisitResult.CONTINUE;
             }
             // 再去遍历删除目录
             @Override
             public FileVisitResult postVisitDirectory(Path dir,
                                             IOException exc) throws IOException {
                Files.delete(dir);
                System.out.printf("文件夹被删除: %s%n", dir);
                return FileVisitResult.CONTINUE;
             }
    
          }
       );
    
    }

    下面的输出体现了文件的删除顺序

    文件被删除 : D:\data\test1\test2\test2.log

    文件被删除 : D:\data\test1\test2\test3\test3.log

    文件夹被删除 : D:\data\test1\test2\test3\test4\test5

    文件夹被删除 : D:\data\test1\test2\test3\test4

    文件夹被删除 : D:\data\test1\test2\test3

    文件夹被删除 : D:\data\test1\test2

    我们既然可以遍历出文件夹或者文件,我们就可以在处理的过程中进行过滤。比如:

    按文件名删除文件或文件夹,参数Path里面含有文件或文件夹名称

    按文件创建时间、修改时间、文件大小等信息去删除文件,参数BasicFileAttributes 里面包含了这些文件信息。

    Files.walk

    如果你对Stream流语法不太熟悉的话,这种方法稍微难理解一点,但是说实话也非常简单。

    使用Files.walk遍历文件夹(包含子文件夹及子其文件),遍历结果是一个Stream

    对每一个遍历出来的结果进行处理,调用Files.delete就可以了。

    @Test
    void testDeleteFileDir6() throws IOException {
       createMoreFiles();
       Path path = Paths.get("D:\data\test1\test2");
    
       try (Stream<Path> walk = Files.walk(path)) {
          walk.sorted(Comparator.reverseOrder())
             .forEach(DeleteFileDir::deleteDirectoryStream);
       }
    
    }
    
    private static void deleteDirectoryStream(Path path) {
       try {
          Files.delete(path);
          System.out.printf("删除文件成功:%s%n",path.toString());
       } catch (IOException e) {
          System.err.printf("无法删除的路径 %s%n%s", path, e);
       }
    }

    问题:怎么能做到先去删除文件,再去删除文件夹?

    利用的是字符串的排序规则,从字符串排序规则上讲,“D:\data\test1\test2”一定排在“D:\data\test1\test2\test2.log”的前面。

    所以我们使用“sorted(Comparator.reverseOrder())”把Stream顺序颠倒一下,就达到了先删除文件,再删除文件夹的目的。

    下面的输出,是最终执行结果的删除顺序。

    删除文件成功:D:\data\test1\test2\test3\test4\test5

    删除文件成功:D:\data\test1\test2\test3\test4

    删除文件成功:D:\data\test1\test2\test3\test3.log

    删除文件成功:D:\data\test1\test2\test3

    删除文件成功:D:\data\test1\test2\test2.log

    删除文件成功:D:\data\test1\test2

    传统IO-递归遍历删除文件夹

    传统的通过递归去删除文件或文件夹的方法就比较经典了

    //传统IO递归删除
    @Test
    void testDeleteFileDir7() throws IOException {
       createMoreFiles();
       File file = new File("D:\data\test1\test2");
       deleteDirectoryLegacyIO(file);
    
    }
    
    private void deleteDirectoryLegacyIO(File file) {
    
       File[] list = file.listFiles();  //无法做到list多层文件夹数据
       if (list != null) {
          for (File temp : list) {     //先去递归删除子文件夹及子文件
             deleteDirectoryLegacyIO(temp);   //注意这里是递归调用
          }
       }
    
       if (file.delete()) {     //再删除自己本身的文件夹
          System.out.printf("删除成功 : %s%n", file);
       } else {
          System.err.printf("删除失败 : %s%n", file);
       }
    }

    需要注意的是:

    listFiles()方法只能列出文件夹下面的一层文件或文件夹,不能列出子文件夹及其子文件。

    先去递归删除子文件夹,再去删除文件夹自己本身。

    以上是如何在Java中刪除檔案或資料夾?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除