This article is the fourth in a series of Java IO summaries.

  • 5 ways to create and write files in Java
  • 6 ways to read data from a file in Java
  • A summary of four Java folder creation methods and their advantages and disadvantages – Java IO basics summary 3

If you finish reading and feel this article is helpful to you, please give me a thumbs-up, your support is my inexhaustible creative power.

To make things easier for you, I’ve created a video for this article: 7 Ways to Delete files or folders

Four basic methods for deleting files or folders

The following four methods can all delete files or folders, but they have one thing in common: they all fail to delete folders that contain child files, which means they can only delete empty folders.

Note that the File class in traditional IO and the Path class in NIO can represent both files and folders.

  • Delete the File class ()
  • The File class deleteOnExit ()
  • Files.delete(Path path)
  • Files.deleteIfExists(Path path);

Differences between them:

The return value of success Failure to verify that the folder does not exist Can check whether the folder is not empty cause of failure note
Delete the File class () true Cannot (return false) Cannot (return false) Traditional IO
The File class deleteOnExit () void No, but if it doesn’t exist, it won’t be deleted Cannot (return void) Traditional IO, this is a pit, avoid using
Files.delete(Path path) void NoSuchFileException DirectoryNotEmptyException NIO, recommended by the authors
Files.deleteIfExists(Path path); true false DirectoryNotEmptyException NIO
  • As can be seen from the above comparison, when the traditional IO method fails to delete a file or folder again, false is returned at most. False: Failed to discover the specific cause of delete failure because the file itself does not exist. Failed to delete because the folder is not empty?
  • NIO method in this point, it is better to do, delete success or failure have specific return value or exception information, which is conducive to us in the deletion of files or folders when the exception processing better procedures
  • Note the traditional IO deleteOnExit method, which I feel should be avoided. It always only returns void and does not throw any exceptions when a deletion fails, so I recommend not using it in case you get no response when a deletion fails and you might think the deletion succeeded.
@test void testDeleteFileDir1() {File File = new File("D:\ data\ Test "); boolean deleted = file.delete(); System.out.println(deleted); @test void testDeleteFileDir2() {File File = new File("D:\ data\ test1"); file.deleteOnExit(); } // If the file does not exist, throw NoSuchFileException // If the folder contains the file, Throw DirectoryNotEmptyException @ Test void testDeleteFileDir3 () throws IOException {Path Path = Paths.get("D:\\data\\test1"); Files.delete(path); // If the file does not exist, return false, indicating that the deletion failed (the file does not exist) Throw DirectoryNotEmptyException @ Test void testDeleteFileDir4 () throws IOException {Path Path = Paths.get("D:\\data\\test1"); boolean result = Files.deleteIfExists(path); System.out.println(result); }Copy the code

Java NIO files.delete (Path Path) and files.deleteifexists (Path Path) are recommended. Delete a file or folder.

How do I delete the entire directory or some files in the directory

As mentioned above, the four apis fail to delete folders if they contain subfiles. So what if we do want to delete the entire folder?

The premise to prepare

To make it easier for us to experiment later, create a directory structure with “.log “ending with data files and other folders

You can create it using the following code

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

2.1. The walkFileTree FileVisitor

  • Use the walkFileTree method to traverse the entire file directory tree, and use FileVisitor to process each file or folder traversed
  • FileVisitor’s visitFile method handles the “files” in the traversal result, so we can delete files in this method
  • FileVisitor’s postVisitDirectory method, notice that the “post” in the method means “to do later…” So use this method to delete the folder can effectively avoid the folder content is not empty exception, because before deleting the folder, the folder inside the file has been deleted.
@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(" file deleted: %s%n", file); return FileVisitResult.CONTINUE; } @override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); System.out.printf(" Folder deleted: %s%n", dir); return FileVisitResult.CONTINUE; }}); }Copy the code

The following output shows the order in which files are deleted

File deleted: D:\data\test1\test2\test2.log file deleted: D:\data\test1\test2\test3\test3.log folder deleted: D:\data\test1\test2\test3\test3.log folder deleted: D:\data\test1\test2\test3\test4\test5 folder deleted: D:\data\test1\test2\test3\test4 folder deleted: D:\data\test1\test2\test3\test4 folder deleted: D:\data\test1\test2\test3 folder deleted: D:\data\test1\test2Copy the code

Now that we can iterate through folders or files, we can filter them as we go along. Such as:

  • Delete a file or folder by file name. The parameter Path contains the file or folder name
  • Delete files by file creation time, file modification time, file size, etc. The BasicFileAttributes parameter contains the file information.

2.2 Files. Walk

If you’re not familiar with the Stream syntax, this method is a little harder to understand, but quite simple to be honest.

  • Walk through the folder (containing subfolders and subfiles) using files. walk, the result of the walk is oneStream<Path>
  • To process each iterated result, call 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(" Delete file successfully: %s%n",path.toString()); } catch (IOException e) {system.err. printf(" undeleted path %s%n%s", path, e); }}Copy the code

Question: how can you delete files first and then delete folders? . D:\data\test1\test2 must precede D:\data\test1\test2\test2.log. Therefore, we use “sorted(comparator.reverseOrder ())” to reverse the Stream order to delete the file first and then the folder.

The following output is the order in which the final execution results are deleted.

Delete file successfully: D:\data\test1\test2\test3\test4\test5 Delete file successfully: D:\data\test1\test2\test3\test4\ test4 delete file successfully: D:\data\test1\test2\test3\test3.log Deleted file successfully: D:\data\test1\test2\test3 deleted file successfully: D:\data\test1\test2\test2.log Deleted file successfully: D:\data\test1\test2\ test3.log Deleted file successfully: D:\data\test1\test2Copy the code

2.3. Traditional IO- Recursive traversal deletes folders

The traditional method of deleting files or folders by recursion is more classical

@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(); // Can not do list multilayer folder data if (list! = null) {for (File temp: list) {// Delete subfolders and subfiles deleteDirectoryLegacyIO(temp); }} if (file.delete()) {system.out.printf (" delete succeeded: %s%n", file); } else {system.err. Printf (" Delete failed: %s%n", file); }}Copy the code

Note that:

  • listFiles()Method can only list files or folders in the layer below a folder, not subfolders and their children.
  • Delete subfolders recursively before deleting the folders themselves

Welcome to my blog, where there are many fine collections

  • This article is reprinted with a credit (must be accompanied by a link, not only the text) : Antetokounmpo blog.

Feel helpful to you, help me like, share! Your support is my inexhaustible creative power! . In addition, the author recently a period of time output as follows boutique content, looking forward to your attention.

  • Spring Boot2.0 by Hand
  • Spring Security- JWT-OAUTH2
  • RBAC Authority Management System for Actual Combat Front-end and Back-end Separation
  • “Actual SpringCloud Micro-service from Bronze to King”
  • VUE Series