FileVisitor Interface

The FileVisitor interface allows us to recursively traverse file structures – folders, sub-folders and files.

Every method of this interface can return 4 possible results (instances of the FileVisitResult enum):

This FileVisitor interface has 4 methods:

  • visitFile():
    The method is invoked for a file. The method should return a FileVisitResult.CONTINUE result or a FileVisitResult.TERMINATE result. The method receive a reference to the file (a Path object) and to the BasicFileAttributes object associated with the Path.
  • preVisitDirectory():
    This method is invoked for a directory before visiting its children. The method returns FileVisitResult.CONTINUE if we want it’s children to be visited or FileVisitResult.SKIP_SUBTREE if we want the process to stop. If we want to skip visiting the siblings of the directory we need to return FileVisitResult.SKIP_SIBLINGS .
  • postVisitDirectory():
    This method is invoked after we visit all the children of a directory (including other folders and their descendants).
  • visitFileFailed():
    This method is invoked if a file (or folder) cannot be accessed.

In practice it is also possible to use the SimpleFileVisitor class if we want to traverse only the directories.

Once we have created the “recursive-walking-mechanism” by implementing FileVisitor interface or by extending the SimpleFileVisitor class we can start the recursive process by calling the walkFileTree() method .


Example: Writing an application that search for files bigger than a pre-defined size

In this example we are going to implement a FileVisitor that walks a folder and logs to output all files that are bigger than certain amount.

The first step is to write the FileVisitor:

The main method:

And some sample output from my machine:


Writing a file search application based on a criteria

We can extend the example from above and create a more general approach.

The idea is to write an abstract implementation of the FileVisitor interface, that contains an abstract method “criteria(Path, BasicFileAttributes)“.

Later we can use anonymous classes to define a new behavior of our visitors specifying only the criteria and avoiding to write the boiler-plate-code necessary to implement a FileVisitor.

We will name our FileVisitor implementation FileSearchByCriteriaVisitor:

This class will have two instance variables called results and failedVisits:

The “criteria(Path, BasicFileAttributes)” mentioned before will be used like this:

Now everytime we implement a new FileSearchByCriteriaVisitor we must supply an implementation for the abstract method defined before.

Example how to use the FileSearchByCriteriaVisitor:

The results and the paths with errors are available in “sizeVisitor.getResults()” and “sizeVisitor.getFailedVisits()”.

Introduction

With NIO.2 we can easily determine the attributes of a file by using the java.nio.file.attribute package.

Various file systems have different properties associated with files but NIO.2 groups the attributes into views, each view is specific to a particular file system implementation.

NIO.2 comes with a set of views:

  • BasicFileAttributeView: This view contains a set of common attributes supported by all filesystem implementations. The inner name of the attribute view is ‘basic’.
  • DosFileAttributeView: This view contains a set of attributes specific to filesystems that implement DOS attributes. The inner name of the attribute view is ‘dos’.
  • PosixFileAttributeView: This view contains a set of attributes specific to file systems that support the POSIX standards. The inner name of the attribute view is ‘posix’.
  • AclFileAttributeView: This view is supported by all filesystems implementations that have the concept of ACL. The inner name of the attribute is ‘acl’.
  • FileOwnerAttributeView: This view is supported by all filesystems implementations that have the concept of “ownership” over a file. The inner name of the attribute is ‘owner’.
  • UserDefinedFileAttributeView

How do we determine what are the views supported by our filesystem ?

Output (I am using a Windows 7 machine):

Everytime we want to access the view attributes of a file/folder, it is advisable to check if the file system supports the particular view. NIO.2 allows us to test this using the FileSystem.supportedFileAttributeViews() method .

Eg.:

Output:


Supported file attributes

Every view support file attributes.

BasicFileAttributeView

Attribute Returned Type Comments
“basic:creationTime” FileTime The exact time when the file was created.
“basic:fileKey” Object An object that uniquely identifies a file or null if a file key is not available.
“basic:isDirectory” Boolean Returns true if the file is a directory.
“basic:isRegularFile” Boolean Returns true if a file is not a directory.
“basic:isSymbolicLink” Boolean Returns true if the file is considered to be a symbolic link.
“basic:isOther” Boolean
“basic:lastAccessTime” FileTime The last time when the file was accesed.
“basic:lastModifiedTime” FileTime The time when the file was last modified.
“basic:size” Long The file size.

DosFileAttributeView

Attribute Returned Type Comments
“dos:archive” Boolean Return true if a file is archive or not.
“dos:hidden” Boolean Returns true if the file/folder is hidden.
“dos:readonly” Boolean Returns true if the file/folder is read-only.
“dos:system” Boolean Returns true if the file/folder is system file.

PosixFileAttributeView

Attribute Returned Type Comments
“posix:permissions” Set<PosixFilePermission> The file permissions.
“posix:group” GroupPrincipal Used to determine access rights to objects in a file system

AclFileAttributeView

Attribute Returned Type
“acl:acl” List<AclEntry>
“acl:owner” UserPrincipal

Retrieving file/folder attributes

There are two ways to extract those attributes:

  • Getting a bulk of attributes using readAttributes() method ;
  • Getting single attributes using getAttribute() method .

Retrieving bulk attributes:

Output:

We can also retrieve single attributes. Example:


Updating file/folder attributes

The simplest way to update file attributes is by using the Files.setAttribute method.
In the following example we are going to modify the creation time of a given file:

Output:


Getting attributes of FileStores

To determine the default FileStore object we can invoke FileSystems.getDefault(), but it’s also possible to obtain the list of FileStores by iterating over the list we obtain calling FileSystem.getFileStores() .

Each file store object has dedicated methods for obtaining the name, type, totalSpace etc.

Output: