Delete files created more than 10 days ago, saving the latest if everyone from the list has more than 10 days of creation

Asked

Viewed 649 times

4

I did this question where doubt was how to delete files with more than 10 days of creation. I recover them from a directory and the code has already been implemented and is functional.

However, I ended up with a problem that can make the code erase all the files, in case the program goes 10 days without running. I need to save the latest file if this occurs, but as I don’t know in what order java recovers that list from windows, I can’t consider that the latest (or the first ad list) would be the latest.

How do I save the latest file by keeping the code deletion structure below? Preferably using java native resources, because I have some limitations that can cause me problems if adding external libs.

public static void removeOldFiles() {

    try {
        //resgato o limite de dias de um arquivo mas
        //estou trabalhando com diasLimite = 10
        Propriedade prop = new Propriedade();
        int diasLimite = Integer.valueOf(prop.getDbBackupDelLimit());
        if (diasLimite > 0) {

            Date data = new Date();
            Calendar c = Calendar.getInstance();
            c.setTime(data);
            //seta a data limite de criação
            //dos backups antigos
            c.add(Calendar.DATE, - diasLimite);
            Date limit = c.getTime();
            //pego a URL da pasta
            File bkpPasta = new File(prop.getDatabaseURL() + prop.getDbBackupDir());
            //listo os arquivos contidos
            File[] arqs = bkpPasta.listFiles();

            for (File f : arqs) {
                //pego a data de ultima modificacao
                //para checar se tem mais de 10 dias 
                Date lastModified = new Date(f.lastModified());
                if (lastModified.before(limit)) {
                    f.delete();
                }
            }
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

Note: Unfortunately I cannot use resources of java 8, because the application was made on top of JDK7.

  • Diego, can’t create a POJO with the file and the date? If yes you can also create Comparator for this date-based POJO, play everything in an orderly data structure and skip the most recent element (which as per the Comparator will be in the first or last position on the list).

  • @Anthonyaccioly didn’t want to increase the complexity too much. I thought of some way to compare the files, saving the most recent one in a temporary variable and deleting the oldest (similar to a vector ordering), but I’m not able to develop the idea on paper :/

  • Diego, realistically, you want something trivial, without the use of libraries and without Java 8 to solve a complex problem. It’s a difficult combination... Either way you will need some sort of sorting to know if all the files are below the limit or not, as well as compare the date of the last modification. While you can scroll through the array the first time to find out which is the latest file and a second to delete all the files (potentially skipping the latest), this will end up meaning more code than the Comparator.

  • @Anthonyaccioly for me, I would use java 8 (because the version that is installed on my machine is the 8) the problem is that these limitations were imposed on me, and as it is a simple and relatively small program, we can not argue this kind of change, Everyone who uses it would have to upgrade to Java 8 and the people here, maybe because it’s public, don’t like "updates" very much. Migrating to 7 was a cost. But you can give me an example of what it would be like with Parator?

  • I have an almost ready answer using a comparator, whether that’s for you or not?

  • @ramaral is native, serves yes

Show 1 more comment

2 answers

7


After having the files in an array:

  • make your order in descending order of the modification date
  • check if the modification date of the first item is more than 10 days old
    • if yes, go through the array, starting from the second item and delete all files.
    • if not, scroll through the array and remove files with modification date greater than 10 days.

Use this comparator

public class LastModifiedFileDescendingComparator implements Comparator<File>{

    @Override
    public int compare(File file1, File file2) {
        long result = file1.lastModified() - file2.lastModified();
        if (result < 0) {
            return 1;
        } else if (result > 0) {
            return -1;
        } else {
            return 0;
        }
    }
}

thus:

Arrays.sort(array, new LastModifiedFileDescendingComparator());

Your code, by using Array.sort() and the best way to calculate the deadline will be like this:

public static void removeOldFiles() {

    long daysToMilliseconds = 24 * 60 * 60 * 1000;

    //resgato o limite de dias de um arquivo mas
    //estou trabalhando com diasLimite = 10
    Propriedade prop = new Propriedade();
    int limiteDays = Integer.valueOf(prop.getDbBackupDelLimit());
    long limiteTime = new Date().getTime() - limitDays * daysToMilliseconds;

    File bkpPasta = new File(prop.getDatabaseURL() + prop.getDbBackupDir());
        //listo os arquivos contidos
    File[] arqs = bkpPasta.listFiles();

    if (limitDays > 0 && arqs.length > 0) {

        //Ordeno os arquivos 
        Arrays.sort(arqs, new LastModifiedFileDescendingComparator());

        //Se o arquivo mais recente estiver dentro do limite, apago a partir do segundo.
        if(shouldDeleteFile(arqs[0], limiteTime)){
            deleteOldFiles(arqs, 1, limiteTime);
        }else{//se não apago a partir do primeiro
            deleteOldFiles(arqs, 0, limiteTime);
        }
    }

}

private void deleteOldFiles(File[] files, int first, long limitTime){
    for (int i = first; i < files.length; i++) {
        if(shouldDeleteFile(files[i], limitTime)){
            files[i].delete();
        }
    }

}
private boolean shouldDeleteFile(File file, long limitTime){
    return file.lastModified() < limitTime;
}

public class LastModifiedFileDescendingComparator implements Comparator<File>{

    @Override
    public int compare(File file1, File file2) {
        long result = file1.lastModified() - file2.lastModified();
        if (result < 0) {
            return 1;
        } else if (result > 0) {
            return -1;
        } else {
            return 0;
        }
    }
}

Note that, using auxiliary methods, the main method became simple and easy to read.

Since removeOldFiles is responsible for getting the files to be deleted and being them files from backup, I would change your name to removeOldBackupFiles.

  • I don’t understand how I’m going to use this class. No Arrays.sort?

  • Yes, I edited the answer.

  • It gives some problem if I use through anonymous class?

  • No, it already implements an interface(Comparator)

  • Thanks, it worked out, I’m breaking my head now to refactor, the code I made using your tip works, but I think I wrote more than you really need to do so little.

  • I don’t think it’s much. However, this can be done without ordering the array.

  • looks like it got http://pastebin.com/m7UkZRts works, does what I need, but I’m finding the code I made (right after.Sort arrays) very repetitive.

  • If you have repeated code extract it to a method. Pass that loop for for a method that receives the array and the first index to be treated.

  • It became much more organized like this, separating responsibilities. Even if I had tried, I wouldn’t have done anything close to this, very good!

  • Just one last question, I didn’t quite understand the utility of the variable daysToMilliseconds.

  • The value returned by file.lastModified() represents this date in milliseconds (UNIX time). The use of milliseconds avoids the need to convert to Date and use a Calendar to calculate the deadline, then make the comparison. The current date in milliseconds is obtained by new Date().getTime(). daysToMilliseconds represents a day in milliseconds, is used to convert the limit of days into milliseconds in the expression new Date().getTime() - limitDays * daysToMilliseconds.

  • The result expresses the value of the cut-off date in milliseconds and can therefore be compared directly with file.lastModified()

  • 1

    I understood now. I could not implement today, tomorrow I will add in the application, thanks for the force :D

Show 8 more comments

3

One option is to sort the list of files using the comparator:

import org.apache.commons.io.comparator.LastModifiedFileComparator;  

The function below sorts the array, ai you can delete from the second item.

File[] arqs = directory.listFiles();
Arrays.sort(arqs, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
for (File file : arqs) {
    Date ultModificado = new Date(file.lastModified());        
}

Source: https://stackoverflow.com/a/24159031/1997073

  • I’ll be honest with you, I’m trying to avoid using external libs, a native solution for me would be much better, I have some restrictions here that, increasing the size of the application jar, can result in problems :/

Browser other questions tagged

You are not signed in. Login or sign up in order to post.