You can delete files, directories or links. With symbolic links, the link is deleted and not the target of the link. With directories, the directory must be empty, or the deletion fails.
The Files
class provides two deletion methods.
The method deletes the file or throws an exception if the deletion fails. For example, if the file does not exist a NoSuchFileException
is thrown. You can catch the exception to determine why the delete failed as follows:
try { Files.delete[path]; } catch [NoSuchFileException x] { System.err.format["%s: no such" + " file or directory%n", path]; } catch [DirectoryNotEmptyException x] { System.err.format["%s not empty%n", path]; } catch [IOException x] { // File permission problems are caught here. System.err.println[x]; }
The method also deletes the file, but if the file does not exist, no exception is thrown. Failing silently is useful when you have multiple threads deleting files and you don't want to throw an exception just because one thread did so first.
Previous articles in this series have covered reading files with Java, writing files, and constructing directory and file paths with the
9 andCode language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
0 classes. This fourth part describes the most important directory and file operations. It answers the following questions:Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
- How to list all files in a directory?
- How to search for files matching specific criteria within a directory tree?
- How to find the current directory?
- How to find the user's home directory?
- How to find the temporary directory, and how to create a temporary file?
- How do I move files with Java?
- How do I rename a file?
- How do I copy a file?
- How to delete a file?
- How to create a symbolic link with Java?
The article answers all questions using the NIO.2 File API, introduced in Java 7 with JSR 203.
Directory operations
For the following directory operations, you need a Path-object representing the directory. You can construct this object using the static method
1 [or, before Java 11, usingCode language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
2].Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
A comprehensive tutorial on constructing directory paths with
0,Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
4, andCode language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
9 can be found in the third part of this series.Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
How to list directory contents with Files.list[]
The easiest way to list the complete contents of a directory is the
6 method. It returns a Stream ofCode language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
0 objects, which we simply write toCode language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
8 in the following example:Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
Code language: Java [java]
Path currentDir = Path.of[System.getProperty["user.home"]]; Files.list[currentDir].forEach[System.out::println];
How to search a directory recursively with Files.list[]
Let's move on to a more complex case. In the following example, we want to output all regular files located in the home directory or a subdirectory of any depth thereof and whose name starts with "settings".
Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
You can use the methods
9 andCode language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
0 to check if a file is a regular file or directory. Another file type is the symbolic link – you can recognize it withCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
1. It is also possible that all three methods returnCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
2, in which case the file is of type "other" [what exactly this could be is unspecified].Code language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
In the example above, we have to catch
3 inside the lambda and wrap it with anCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
4 because theCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
5 consumer of the stream must not throw a checked exception.Code language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
How to search a directory recursively with Files.walk[]
You can write the previous example much shorter and more elegant – using
6:
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
Code language: Java [java]
Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
However, this variant has the disadvantage that an
7 cannot be caught individually as before. If such an exception occurs here, the entireCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
6 method terminates. If this is acceptable for your application, this way is more beautiful than the previous one.Code language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
How to search a directory recursively with Files.walkFileTree[]
Another variant is
9. This method implements the visitor pattern. It sends each file within the directory structure to aCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
0, which you pass to the method. In the following example, we use theCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
1 class, which implements all methods ofCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
0. We only override theCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
3 method:Code language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
Code language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
The method's return value,
4, indicates thatCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
5 should continue to traverse the directory tree. Other return values would be:Code language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
6 – terminates the
Code language: Java [java]private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
5 method.
Code language: Java [java]private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
8 – skips all other files of the current directory.
Code language: Java [java]private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
9 – skips the current directory – this return value cannot be returned by
Code language: Java [java]private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
3, but by
Code language: Java [java]private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
1.
Code language: Java [java]private static void findFileWithFind[Path currentDir, String fileNamePrefix] throws IOException { Files.find[currentDir, Integer.MAX_VALUE, [path, attributes] -> Files.isRegularFile[path] && path.getFileName[].toString[].startsWith[fileNamePrefix]] .forEach[System.out::println]; }
The
5 variant, too, would terminate processing in the case of anCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
7. However, there is a way to prevent this. To do so, you also need to overwrite the methodCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
4:Code language: Java [java]
private static void findFileWithFind[Path currentDir, String fileNamePrefix] throws IOException { Files.find[currentDir, Integer.MAX_VALUE, [path, attributes] -> Files.isRegularFile[path] && path.getFileName[].toString[].startsWith[fileNamePrefix]] .forEach[System.out::println]; }
Code language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed[Path file, IOException exc] throws IOException { if [exc instanceof AccessDeniedException] { System.out.println["Access denied: " + file]; return FileVisitResult.CONTINUE; } else { return super.visitFileFailed[file, exc]; } } }]; }
How to search a directory with Files.find[]
An alternative approach is the
5 method. It expects a "matcher" as the third parameter: this is a function that has aCode language: Java [java]
private static void findFileWithFind[Path currentDir, String fileNamePrefix] throws IOException { Files.find[currentDir, Integer.MAX_VALUE, [path, attributes] -> Files.isRegularFile[path] && path.getFileName[].toString[].startsWith[fileNamePrefix]] .forEach[System.out::println]; }
0 andCode language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
7 as input parameters and returns aCode language: Java [java]
private static void findFileWithFind[Path currentDir, String fileNamePrefix] throws IOException { Files.find[currentDir, Integer.MAX_VALUE, [path, attributes] -> Files.isRegularFile[path] && path.getFileName[].toString[].startsWith[fileNamePrefix]] .forEach[System.out::println]; }
8 indicating whether the corresponding file should be included in the result or not.Code language: Java [java]
private static void findFileWithFind[Path currentDir, String fileNamePrefix] throws IOException { Files.find[currentDir, Integer.MAX_VALUE, [path, attributes] -> Files.isRegularFile[path] && path.getFileName[].toString[].startsWith[fileNamePrefix]] .forEach[System.out::println]; }
Code language: Java [java]
private static void findFileWithFind[Path currentDir, String fileNamePrefix] throws IOException { Files.find[currentDir, Integer.MAX_VALUE, [path, attributes] -> Files.isRegularFile[path] && path.getFileName[].toString[].startsWith[fileNamePrefix]] .forEach[System.out::println]; }
Again, an
7 would end the entire search prematurely. I don't know of any way to circumvent this with
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
Code language: Java [java]
5. If you expect subdirectories with denied access, you should either useCode language: Java [java]
private static void findFileWithFind[Path currentDir, String fileNamePrefix] throws IOException { Files.find[currentDir, Integer.MAX_VALUE, [path, attributes] -> Files.isRegularFile[path] && path.getFileName[].toString[].startsWith[fileNamePrefix]] .forEach[System.out::println]; }
9 and overwrite theCode language: Java [java]
private static void findFileWithWalkFileTree[ Path currentDir, String fileNamePrefix] throws IOException { Files.walkFileTree[currentDir, new SimpleFileVisitor[] { @Override public FileVisitResult visitFile[Path file, BasicFileAttributes attrs] throws IOException { if [Files.isRegularFile[file] && file.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[file]; } return FileVisitResult.CONTINUE; } }]; }
2 method to catch the exception. Alternatively, useCode language: Java [java]
Path currentDir = Path.of[System.getProperty["user.dir"]];
6 and implement the recursion yourself.Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
Accessing specific directories
Attention: If you are using a version older than Java 11, you must replace
1 withCode language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
2 in the following code examples.Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
Accessing the current directory
The current directory can be found via the system property "user.dir":
Code language: Java [java]
Path currentDir = Path.of[System.getProperty["user.dir"]];
Accessing the user's home directory
You can find the home directory of the current user via the system property "user.home":
Code language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
Accessing the temporary directory
And you can find the temporary directory via the system property "java.io.tmpdir":
Code language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
If you want to create a temporary file in the temporary directory, you do not need to access the temporary directory first. There is a shortcut for this. You will find it at the beginning of the following chapter, "File operations".
File operations
How to create a temporary file
After the last chapter concluded with accessing the temporary directory, this one starts with a shortcut to creating temporary files:
Code language: Java [java]
Path tempFile = Files.createTempFile["happycoders-", ".tmp"];
The two parameters are a prefix and a suffix. The
6 method will insert a random number between them. When I run the method repeatedly on my Windows system and print the variableCode language: Java [java]
Path currentDir = Path.of[System.getProperty["user.dir"]];
7 to the console, I get the following output:Code language: Java [java]
Path currentDir = Path.of[System.getProperty["user.dir"]];
0Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
On Linux it looks like this:
1Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
It is essential to know that
6 does not only create the respectiveCode language: Java [java]
Path currentDir = Path.of[System.getProperty["user.dir"]];
0 object but actually creates an empty file.Code language: Java [java]
private static void findFileWithWalk[Path currentDir, String fileNamePrefix] throws IOException { Files.walk[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } }]; }
How to move a file in Java
To move a file, use the method
0. The following example creates a temporary file and moves it to the home directory of the logged-on user:Code language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
2Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
The second parameter of the
1 method must represent the target file, not the target directory! If you invokedCode language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
2 here, you would get aCode language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
3. Therefore, in the example, we use theCode language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
4 method to concatenate the
Path homeDir = Path.of[System.getProperty["user.home"]];
Code language: Java [java]
5 with the name of the file to be copied.Code language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
How to move a directory including all subdirectories
You can move a directory just like a file. In the following example, we create two temporary directories and one file in the first directory. We then move the first directory into the second:
3Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
How to rename file with Java
After all, renaming a file [or a directory] is a special case of moving, with the destination directory being the same as the source directory and only the file name changing. In the following example, we rename a temporary file to "happycoders.tmp":
4Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
Invoking
6 is a shortcut forCode language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
7: The directory is extracted from the source file and concatenated with the new file name.Code language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
How to copy a file in Java
Copying a file is similar to renaming it. The following example copies a temporary file to the home directory:
5Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
This method has a significant advantage over proprietary implementations with
8 andCode language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
9, as they were necessary before Java 7 and the NIO.2 File API:Code language: Java [java]
Path homeDir = Path.of[System.getProperty["user.home"]];
0 delegates the call to operating system-specific – and thus optimized – implementations.Code language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
How to delete a file in Java
You can delete a file [or a directory] with
1:Code language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
6Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
The directory on which you invoke
1 must be empty. Otherwise, the method will throw aCode language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
3. You can try this with the following code:Code language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
7Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
First, a temporary directory is created, then a temporary file in it. Then an attempt is made to delete the [non-empty] directory.
How to create a symbolic link to a file
You can create a symbolic link with the method
4. Attention: You have to specify target and source in reverse order as with all previous methods: first, the link path, then the path of the file to be linked. The following example creates a temporary file and then sets a symbolic link to the created file from the home directory.Code language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
8Code language: Java [java]
import java.io.*; import java.nio.file.*; public class FindFilesRecursivelyExample { public static void main[String[] args] throws IOException { Path currentDir = Path.of[System.getProperty["user.home"]]; findFileRecursively[currentDir, "settings"]; } private static void findFileRecursively[ Path currentDir, String fileNamePrefix] throws IOException { Files.list[currentDir].forEach[child -> { if [Files.isRegularFile[child] && child.getFileName[].toString[].startsWith[fileNamePrefix]] { System.out.println[child]; } if [Files.isDirectory[child] ] { try { findFileRecursively[child, fileNamePrefix]; } catch [AccessDeniedException e] { System.out.println["Access denied: " + child]; } catch [IOException e] { throw new UncheckedIOException[e]; } } }]; } }
This example works on Linux without restrictions. On Windows, you need administrative rights to create symbolic links. If these are missing, the following exception is thrown:
5Code language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
Summary and outlook
This fourth article in the series about files in Java introduced the most important directory and file operations.
In the next part, I will show you how to write and read structured data with
6 andCode language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
7.Code language: Java [java]
Path tempDir = Path.of[System.getProperty["java.io.tmpdir"]];
We then move on to the following advanced topics:
- NIO channels and buffers introduced in Java 1.4, to speed up working with large files
- for convenient and blazing-fast file access without streams
- , to access the same files in parallel – i.e., from several threads or processes – without conflict
As always, I appreciate it if you share the article or your feedback via the comment function. Would you like to be informed when the next part is published? Then to sign up for the HappyCoders newsletter.