How to delete unwanted files in a folder recursively using Java’s FileVisitor?

Photo by Pixabay on Pexels.com

Java 7 came up with a new package for dealing with file systems : java.nio.file.

It provides a better interface compared to the previous versions to deal with files and directories.

One such feature is to traverse all the sub folders and files inside a folder recursively and perform any file operations on them.

To walk a folder tree all you have to do in Java 7 is call the below method:

Files.walkFileTree(Path path,FileVisitor fileVisitor );

As you see it takes two arguments.

The first one represents the parent folder .

The second one represents the file visitor which is used to perform any operation on the files and folders.

Let’s use this method to delete all files ending with .log from a folder recursively (from the parent folder and sub folders)

To do this you need to pass the parent folder path first.

This can be passed as :

Path.of("G://testfolder");

(G://testfolder is the parent folder I used in my machine to test this. I created three sub folders subfolder1,subfolder2 and subfolder 3 under this parent folder and created two more sub folders under subfolder1 – subfolder11 and subfolder12. I placed a file ending with .log in subfolder11, subfolder12 and subfolder3)

For the file visitor to be passed as a second argument , let’s create one.

FileVisitor interface in Java , provides four methods to deal with traversing a directory and modifying it:

  • preVisitDirectory() – to do something on a directory before visiting it . We will use this to calculate the number of files ending with .log inside the directory
  • visitFile() – to do something on the file visited. We will use this to delete the file if it ends with a .log extension
  • postVisitDirectory() – to do something on a directory after visiting it. We will use this to again calculate the number of files ending with .log . It should be zero since we will delete them using visitFile() method.
  • visitFileFailed() – to do something if there is any issue with a file to be visited. We will not use this in this demo.

Java provides a basic implementation of FileVisitor interface named SimpleFileVisitor. We will create a class extending this class and override the three methods as mentioned above.

Inside this visitor to find if a file ends with .log we will use PathMatcher interface provided by Java.

The below code creates a matcher which can then be used to find if a file matches the pattern specified by it:

PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.{log}");

In the above method getPathMatcher(), we need to pass in the pattern of file to be matched. “glob” is a type of syntax expression just like regular expressions. It is commonly used for matching file patterns. Instead regular expressions can also be used.

In the above case any file which ends with .log is matched using the expression *.{log}.

Once the matcher is created , you can use it to match file patterns like this :

boolean fileMatches = matcher.matches(file.getFileName());

Let’s go back to the file visitor now .

Below is the file visitor I created:

package com.filevisitor.demo;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class UnwantedFilesVisitor extends SimpleFileVisitor<Path> {

	PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.{log}");

	@Override
	public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {

		System.out.println("Before directory visit");

		System.out.println("No of unwanted (log) files in directory: " + dir.getFileName() + " - "
				+ Files.list(dir).filter(file -> matcher.matches(file.getFileName())).count());

		return FileVisitResult.CONTINUE;

	}

	@Override
	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {

		if (matcher.matches(file.getFileName())) {

			Files.delete(file);

		}
		return FileVisitResult.CONTINUE;
	}

	@Override
	public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {

		System.out.println("Post directory visit:");

		System.out.println("No of unwanted (log) files in directory: " + dir.getFileName() + " - "
				+ Files.list(dir).filter(file -> matcher.matches(file.getFileName())).count());

		return FileVisitResult.CONTINUE;
	}

}

In the preVisitDirectory() method , all the files which end with .log are filtered out and their count is calculated.

In visitFile() method , any file which ends with .log is deleted

In postVisitDirectory() method , again the count of files ending with .log is taken and it should be zero if all the log files were deleted.

All the methods return FileVisitorResult.CONTINUE to continue traversing the folder tree until every directory/file is visited.

Here is how to use the above file visitor in client code:

package com.filevisitor.demo;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class Client {

	
	
	public static void main(String a[]) {
		
		
		try {
			Files.walkFileTree(Path.of("G://testfolder"), new UnwantedFilesVisitor());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

That’s it!

On running the above class , the below output got printed and all the log files got deleted:

Before directory visit
No of unwanted (log) files in directory: testfolder - 0
Before directory visit
No of unwanted (log) files in directory: subfolder1 - 0
Before directory visit
No of unwanted (log) files in directory: subfolder11 - 1
Post directory visit:
No of unwanted (log) files in directory: subfolder11 - 0
Before directory visit
No of unwanted (log) files in directory: subfolder12 - 1
Post directory visit:
No of unwanted (log) files in directory: subfolder12 - 0
Post directory visit:
No of unwanted (log) files in directory: subfolder1 - 0
Before directory visit
No of unwanted (log) files in directory: subfolder2 - 0
Post directory visit:
No of unwanted (log) files in directory: subfolder2 - 0
Before directory visit
No of unwanted (log) files in directory: subfolder3 - 1
Post directory visit:
No of unwanted (log) files in directory: subfolder3 - 0
Post directory visit:
No of unwanted (log) files in directory: testfolder - 0

Here is the link to to code:

https://github.com/vijaysrj/filevisitorjava7


Posted

in

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading