Bogdan
Bogdan

Reputation: 155

Delete folder older than one day in java

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

Answers (2)

VasileM
VasileM

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();
        }
    }
  1. Check recursively all subfolders of testFolder and save a Path of every folder than has been modified before this period of time: Period.ofDays(1)
  2. Delete (recursively) all folders saved previously (Paths)

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

Sundeep
Sundeep

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

Related Questions