web-dev-qa-db-fra.com

Supprimer les fichiers de plus de x jours

Comment puis-je savoir quand un fichier a été créé avec Java, étant donné que je souhaite supprimer des fichiers plus anciens qu'une certaine période, je supprime actuellement tous les fichiers d'un répertoire, mais ce n'est pas idéal:

public void DeleteFiles() {
    File file = new File("D:/Documents/NetBeansProjects/printing~Subversion/fileupload/web/resources/pdf/");
    System.out.println("Called deleteFiles");
    DeleteFiles(file);
    File file2 = new File("D:/Documents/NetBeansProjects/printing~Subversion/fileupload/Uploaded/");
    DeleteFilesNonPdf(file2);
}

public void DeleteFiles(File file) {
    System.out.println("Now will search folders and delete files,");
    if (file.isDirectory()) {
        for (File f : file.listFiles()) {
            DeleteFiles(f);
        }
    } else {
        file.delete();
    }
}

Au-dessus de mon code actuel, j'essaye maintenant d’ajouter une instruction if qui ne supprimera que les fichiers plus anciens que disons une semaine. 

MODIFIER:

@ViewScoped
@ManagedBean
public class Delete {

    public void DeleteFiles() {
        File file = new File("D:/Documents/NetBeansProjects/printing~Subversion/fileupload/web/resources/pdf/");
        System.out.println("Called deleteFiles");
        DeleteFiles(file);
        File file2 = new File("D:/Documents/NetBeansProjects/printing~Subversion/fileupload/Uploaded/");
        DeleteFilesNonPdf(file2);
    }

    public void DeleteFiles(File file) {
        System.out.println("Now will search folders and delete files,");
        if (file.isDirectory()) {
            System.out.println("Date Modified : " + file.lastModified());
            for (File f : file.listFiles()) {
                DeleteFiles(f);
            }
        } else {
            file.delete();
        }
    }

Ajout d'une boucle maintenant.

MODIFIER

J'ai remarqué en testant le code ci-dessus que je reçois la dernière modification dans:

INFO: Date Modified : 1361635382096

Comment dois-je coder la boucle if pour dire si elle a plus de 7 jours, supprimez-la lorsqu'elle est dans le format ci-dessus?

30
user2065929

Vous pouvez utiliser File.lastModified() pour obtenir la dernière heure de modification d’un fichier/répertoire.

Peut être utilisé comme ceci:

long diff = new Date().getTime() - file.lastModified();

if (diff > x * 24 * 60 * 60 * 1000) {
    file.delete();
}

Ce qui supprime les fichiers de plus de x (un int) jours.

40
Nishant Shreshth

Commons IO _ supporte le filtrage des fichiers par âge avec son AgeFileFilter . Votre DeleteFiles pourrait ressembler à ceci:

import Java.io.File;
import org.Apache.commons.io.FileUtils;
import org.Apache.commons.io.filefilter.AgeFileFilter;
import static org.Apache.commons.io.filefilter.TrueFileFilter.TRUE;

// a Date defined somewhere for the cutoff date
Date thresholdDate = <the oldest age you want to keep>;

public void DeleteFiles(File file) {
    Iterator<File> filesToDelete =
        FileUtils.iterateFiles(file, new AgeFileFilter(thresholdDate), TRUE);
    for (File aFile : filesToDelete) {
        aFile.delete();
    }
}

Update: Pour utiliser la valeur donnée dans votre édition, définissez la thresholdDate comme suit:

Date tresholdDate = new Date(1361635382096L);
23
Ryan Stewart

Exemple utilisant l'API Time de Java 8

LocalDate today = LocalDate.now();
LocalDate eailer = today.minusDays(30);

Date threshold = Date.from(eailer.atStartOfDay(ZoneId.systemDefault()).toInstant());
AgeFileFilter filter = new AgeFileFilter(threshold);

File path = new File("...");
File[] oldFolders = FileFilterUtils.filter(filter, path);

for (File folder : oldFolders) {
    System.out.println(folder);
}
10
MadProgrammer

Utiliser Apache utils est probablement le plus simple. Voici la solution la plus simple que je pourrais trouver.

public void deleteOldFiles() {
    Date oldestAllowedFileDate = DateUtils.addDays(new Date(), -3); //minus days from current date
    File targetDir = new File("C:\\TEMP\\archive\\");
    Iterator<File> filesToDelete = FileUtils.iterateFiles(targetDir, new AgeFileFilter(oldestAllowedFileDate), null);
    //if deleting subdirs, replace null above with TrueFileFilter.INSTANCE
    while (filesToDelete.hasNext()) {
        FileUtils.deleteQuietly(filesToDelete.next());
    }  //I don't want an exception if a file is not deleted. Otherwise use filesToDelete.next().delete() in a try/catch
}
9
MattC

Pour une solution JDK 8 utilisant à la fois des flux de fichiers NIO et JSR-310

long cut = LocalDateTime.now().minusWeeks(1).toEpochSecond(ZoneOffset.UTC);
Path path = Paths.get("/path/to/delete");
Files.list(path)
        .filter(n -> {
            try {
                return Files.getLastModifiedTime(n)
                        .to(TimeUnit.SECONDS) < cut;
            } catch (IOException ex) {
                //handle exception
                return false;
            }
        })
        .forEach(n -> {
            try {
                Files.delete(n);
            } catch (IOException ex) {
                //handle exception
            }
        });

Le problème ici est la nécessité de gérer les exceptions dans chaque lambda. Il aurait été intéressant que l'API ait des surcharges UncheckedIOException pour chaque méthode IO. Avec des aides pour le faire, on pourrait écrire:

public static void main(String[] args) throws IOException {
    long cut = LocalDateTime.now().minusWeeks(1).toEpochSecond(ZoneOffset.UTC);
    Path path = Paths.get("/path/to/delete");
    Files.list(path)
            .filter(n -> Files2.getLastModifiedTimeUnchecked(n)
                    .to(TimeUnit.SECONDS) < cut)
            .forEach(n -> {
                System.out.println(n);
                Files2.delete(n, (t, u)
                              -> System.err.format("Couldn't delete %s%n",
                                                   t, u.getMessage())
                );
            });
}


private static final class Files2 {

    public static FileTime getLastModifiedTimeUnchecked(Path path,
            LinkOption... options)
            throws UncheckedIOException {
        try {
            return Files.getLastModifiedTime(path, options);
        } catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    public static void delete(Path path, BiConsumer<Path, Exception> e) {
        try {
            Files.delete(path);
        } catch (IOException ex) {
            e.accept(path, ex);
        }
    }

}
5
Brett Ryan

Utilisation de lambdas (Java 8+)

Option non récursive pour supprimer tous les fichiers du dossier en cours datant de plus de N jours (ignore les sous-dossiers):

public static void deleteFilesOlderThanNDays(int days, String dirPath) throws IOException {
    long cutOff = System.currentTimeMillis() - (days * 24 * 60 * 60 * 1000);
    Files.list(Paths.get(dirPath))
    .filter(path -> {
        try {
            return Files.isRegularFile(path) && Files.getLastModifiedTime(path).to(TimeUnit.MILLISECONDS) < cutOff;
        } catch (IOException ex) {
            // log here and move on
            return false;
        }
    })
    .forEach(path -> {
        try {
            Files.delete(path);
        } catch (IOException ex) {
            // log here and move on
        }
    });
}

Option récursive, qui traverse les sous-dossiers et supprime tous les fichiers de plus de N jours:

public static void recursiveDeleteFilesOlderThanNDays(int days, String dirPath) throws IOException {
    long cutOff = System.currentTimeMillis() - (days * 24 * 60 * 60 * 1000);
    Files.list(Paths.get(dirPath))
    .forEach(path -> {
        if (Files.isDirectory(path)) {
            try {
                recursiveDeleteFilesOlderThanNDays(days, path.toString());
            } catch (IOException e) {
                // log here and move on
            }
        } else {
            try {
                if (Files.getLastModifiedTime(path).to(TimeUnit.MILLISECONDS) < cutOff) {
                    Files.delete(path);
                }
            } catch (IOException ex) {
                // log here and move on
            }
        }
    });
}
3
rouble

Voici la version Java 8 utilisant Time API. Il a été testé et utilisé dans notre projet:

    public static int deleteFiles(final Path destination,
        final Integer daysToKeep) throws IOException {

    final Instant retentionFilePeriod = ZonedDateTime.now()
            .minusDays(daysToKeep).toInstant();

    final AtomicInteger countDeletedFiles = new AtomicInteger();
    Files.find(destination, 1,
            (path, basicFileAttrs) -> basicFileAttrs.lastModifiedTime()
                    .toInstant().isBefore(retentionFilePeriod))
            .forEach(fileToDelete -> {
                try {
                    if (!Files.isDirectory(fileToDelete)) {
                        Files.delete(fileToDelete);
                        countDeletedFiles.incrementAndGet();
                    }
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            });

    return countDeletedFiles.get();
}
3
Erikson

Une autre approche avec Apache commons-io et joda:

private void deleteOldFiles(String dir, int daysToRemainFiles) {
    Collection<File> filesToDelete = FileUtils.listFiles(new File(dir),
            new AgeFileFilter(DateTime.now().withTimeAtStartOfDay().minusDays(daysToRemainFiles).toDate()),
            TrueFileFilter.TRUE);    // include sub dirs
    for (File file : filesToDelete) {
        boolean success = FileUtils.deleteQuietly(file);
        if (!success) {
            // log...
        }
    }
}
3
Isaace

Vous pouvez obtenir la date de création du fichier en utilisant NIO, en procédant comme suit:

BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
System.out.println("creationTime: " + attrs.creationTime());

Pour en savoir plus, consultez la page: http://docs.Oracle.com/javase/tutorial/essential/io/fileAttr.html

2
vikasing

Voici le code pour supprimer les fichiers non modifiés depuis six mois et créer le fichier journal.

package deleteFiles;

import Java.io.File;
import Java.io.IOException;
import Java.util.ArrayList;
import Java.util.Calendar;
import Java.util.Date;
import Java.util.logging.FileHandler;
import Java.util.logging.Logger;
import Java.util.logging.SimpleFormatter;

public class Delete {
    public static void deleteFiles()
    {
        int numOfMonths = -6;
        String path="G:\\Files";
        File file = new File(path);
        FileHandler fh;
        Calendar sixMonthAgo = Calendar.getInstance();
        Calendar currentDate = Calendar.getInstance();
        Logger logger = Logger.getLogger("MyLog");
        sixMonthAgo.add(Calendar.MONTH, numOfMonths);
        File[] files = file.listFiles();
        ArrayList<String> arrlist = new ArrayList<String>();

        try {
            fh = new FileHandler("G:\\Files\\logFile\\MyLogForDeletedFile.log");
            logger.addHandler(fh);
            SimpleFormatter formatter = new SimpleFormatter();
            fh.setFormatter(formatter);

            for (File f:files)
            {
                if (f.isFile() && f.exists())
                {
                    Date lastModDate = new Date(f.lastModified());
                    if(lastModDate.before(sixMonthAgo.getTime()))
                    {
                        arrlist.add(f.getName());
                        f.delete();
                    }
                }
            }
            for(int i=0;i<arrlist.size();i++)
                logger.info("deleted files are ===>"+arrlist.get(i));
        }
        catch ( Exception e ){
            e.printStackTrace();
            logger.info("error is-->"+e);
        }
    }
    public static void main(String[] args)
    {
        deleteFiles();
    }
}
0
Pankaj Dagar

Besoin de signaler un bogue sur la première solution listée, x * 24 * 60 * 60 * 1000 atteindra sa valeur maximale si x est grand Donc, besoin de le lancer à long terme

long diff = new Date().getTime() - file.lastModified();

if (diff > (long) x * 24 * 60 * 60 * 1000) {
    file.delete();
}
0
Feng Zhang

Utilisation de fichiers NIO Java avec lambdas & Commons IO

final long time = new Date().getTime();
// Only show files & directories older than 2 days
final long maxdiff = TimeUnit.DAYS.toMillis(2);

Répertoriez tous les fichiers et répertoires trouvés:

Files.newDirectoryStream(Paths.get("."), p -> (time - p.toFile().lastModified()) < maxdiff)
.forEach(System.out::println);

Ou supprimez les fichiers trouvés avec FileUtils :

Files.newDirectoryStream(Paths.get("."), p -> (time - p.toFile().lastModified()) < maxdiff)
.forEach(p -> FileUtils.deleteQuietly(p.toFile()));
0
socona