Reputation: 155
I am trying to delete all folders older that one day from a path in java using the following code:
public static void removeDirectory(File dir) {
long purgeTime = System.currentTimeMillis() - (1 * 24 * 60 * 60 * 1000);
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File aFile : files) {
if (aFile.lastModified() < purgeTime) {
removeDirectory(aFile);
}
}
dir.delete();
} else {
dir.delete();
}
}
public static void createBackupFS(java.awt.event.ActionEvent evt) {
File directory = new File(pathsavefsbackup.getText());
removeDirectory(directory);
}
The only thing that is happening is that the old files are modified with the current time. Mention that the root folder has a folder in it which has files inside it.
Path structure:
root folder - last modified (2 days ago) -> test folder last modified (2 days ago) -> file1.jpg (last modified 3 days ago), file2.txt (last modified 4 days ago).
Could any one help me?
Thank you!
Upvotes: 0
Views: 4510
Reputation: 626
Java NIO2 (Path, Files, FileVisitor)
I'm using 2 classes that implements FileVisitor
interface.
The first one detects all folders/subfolders that has been modified before X period of time.
The second one deletes all folders stored by the first class
Files.walkFileTree(Path, FileVisitor<Class>)
is used to walk through directories.
All classes inside one (you can extract FileVisitorFolders
and FileVisitorDeleteFolders
to class file
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Instant;
import java.time.Period;
import java.util.ArrayList;
public class Main {
private static class FileVisitorFolders implements FileVisitor<Path> {
private Instant beforePeriodOfTime;
private ArrayList<Path> directories = new ArrayList<>(10);
public FileVisitorFolders(Period time) {
beforePeriodOfTime = Instant.now().minus(time);
}
public ArrayList<Path> getDirectories() {
return directories;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
var lastModifiedTime = Files.getLastModifiedTime(dir, LinkOption.NOFOLLOW_LINKS);
if (lastModifiedTime.toInstant().isBefore(beforePeriodOfTime)) {
directories.add(dir);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
}
private static class FileVisitorDeleteFolders implements FileVisitor<Path> {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
}
public static void main(String[] args) {
var fileVisitorFolders = new FileVisitorFolders(Period.ofDays(1));
var fileVisitorDeleteFolder = new FileVisitorDeleteFolders();
try {
Files.walkFileTree(Paths.get("testFolder"), fileVisitorFolders);
for (Path dir : fileVisitorFolders.getDirectories()) {
System.out.printf("Deleting: %s\n", dir.toAbsolutePath().toString());
Files.walkFileTree(dir, fileVisitorDeleteFolder);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
How it works?
Here we have the next directories: (Note: Today is 2018-06-18)
tree -D testFolder/
testFolder/
├── [Jun 17 5:00] a
├── [Jun 18 18:06] b
├── [Jun 15 5:00] c
│ ├── [Jun 18 18:06] e
│ └── [Jun 18 18:06] hi
└── [Jun 18 17:30] e
5 directories, 1 file
The folders a
has been modified 1 day ago and the folder c
has been modified 3 days ago.
The folder a
is empty and the folder c
have a subfolder e
and a file hi
The main method is:
public static void main(String[] args) {
var fileVisitorFolders = new FileVisitorFolders(Period.ofDays(1));
var fileVisitorDeleteFolder = new FileVisitorDeleteFolders();
try {
Files.walkFileTree(Paths.get("testFolder"), fileVisitorFolders);
for (Path dir : fileVisitorFolders.getDirectories()) {
System.out.printf("Deleting: %s\n", dir.toAbsolutePath().toString());
Files.walkFileTree(dir, fileVisitorDeleteFolder);
}
} catch (IOException e) {
e.printStackTrace();
}
}
testFolder
and save a Path of every folder than has been modified before this period of time: Period.ofDays(1)
Output:
Deleting: /root/IdeaProjects/DeleteFolder/testFolder/a
Deleting: /root/IdeaProjects/DeleteFolder/testFolder/c
Process finished with exit code 0
Now we have:
tree -D testFolder/
testFolder/
├── [Jun 18 18:06] b
└── [Jun 18 17:30] e
2 directories, 0 files
Note: Before use it, test it commenting the line: //Files.walkFileTree(dir, fileVisitorDeleteFolder);
To change the date of last modified file/folder (on Linux) you can use the command touch
like:
touch -m -t 201806150700 folderName/fileName
-m
-> last modified time
-t
-> time
If you want less code, use extends SimpleFileVisitor
instead implements FileVisitor
and only implements the necessary methods (omit all empty methods)
If you are using Java before 1.10 replace var
with the instance type.
Important Be carefull with this code. If the parent folder (in this case: testFolder) has not been modified in the last period of time it will be deleted too.
To avoid this situation you can modify the main method:
public static void main(String[] args) {
var parent = Paths.get("testFolder");
var fileVisitorFolders = new FileVisitorFolders(Period.ofDays(1));
var fileVisitorDeleteFolder = new FileVisitorDeleteFolders();
try {
Files.walkFileTree(parent, fileVisitorFolders);
var foldersToDelete = fileVisitorFolder.getDirectories();
foldersToDelete.remove(parent);
for (Path dir : foldersToDelete) {
System.out.printf("Deleting: %s\n", dir.toAbsolutePath().toString());
Files.walkFileTree(dir, fileVisitorDeleteFolder);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Upvotes: 1
Reputation: 472
the for loop is looping through every file in the given folder
for (File aFile : files)
so all you have to do is to check if the current file is older than 24 hour or not if it is delete it otherwise not. You do not need to overcomplicate the code here is the modified version of your code.
The below code delete any folder/file in given directory older than 1 Day
public static void removeDirectory(File dir) {
boolean delSource = false;
long purgeTime = System.currentTimeMillis() - (10 * 1000);
if (dir.lastModified()< purgeTime) delSource = true;
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File aFile : files) {
if (aFile.lastModified() < purgeTime) {
aFile.delete();
}
}
}
if(delSource) dir.delete();
}
public static void createBackupFS() {
File directory = new File("F:\\document\\eclipse\\JavaAZ\\src\\Delete");
removeDirectory(directory);
}
PS: if there are files inside files and so on you have to use recursion for that
Recursive Solution for all files and folder
public static void removeDirectory(File dir) {
long purgeTime = System.currentTimeMillis() - (1 * 24 * 60 * 60 * 1000);
if(dir.isDirectory() == false && dir.lastModified() < purgeTime) dir.delete();
else if (dir.isDirectory() == true && dir.lastModified() < purgeTime) recursiveDelete(dir);
else if(dir.isDirectory()){
File[] files = dir.listFiles();
for (File aFile : files)
removeDirectory(aFile);
}
}
public static void createBackupFS() {
File directory = new File("F:\\downloads\\Compressed\\backup");
removeDirectory(directory);
}
public static void recursiveDelete(File file) {
if (!file.exists())
return;
if (file.isDirectory()) {
for (File f : file.listFiles()) {
recursiveDelete(f);
}
}
file.delete();
}
Upvotes: 1