ti-enxame.com

Excluir arquivos com mais de x dias

Como posso descobrir quando um arquivo foi criado usando Java, como desejo excluir arquivos mais antigos que um determinado período de tempo, atualmente estou excluindo todos os arquivos em um diretório, mas isso não é ideal:

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();
    }
}

Acima está o meu código atual, estou tentando agora adicionar uma instrução if, que excluirá apenas arquivos com mais de uma semana. 

EDITAR:

@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();
        }
    }

Adicionando um loop agora.

EDITAR

Eu tenho notado ao testar o código acima eu recebo a última modificação em:

INFO: Date Modified : 1361635382096

Como devo codificar o loop if para dizer se é mais antigo do que 7 dias excluí-lo quando está no formato acima?

30
user2065929

Você pode usar File.lastModified() para obter o horário da última modificação de um arquivo/diretório.

Pode ser usado assim:

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

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

Que exclui arquivos com mais de x (um int) dias.

40
Nishant Shreshth

Commons IO tem suporte embutido para filtrar arquivos por idade com seu AgeFileFilter . Sua DeleteFiles poderia ficar assim:

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: Para usar o valor conforme indicado em sua edição, defina a thresholdDate como:

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

Exemplo usando a API de tempo do 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

Usar o Apache utils é provavelmente o mais fácil. Aqui está a solução mais simples que eu poderia encontrar.

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

Para uma solução JDK 8 usando fluxos de arquivos NIO e 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
            }
        });

A coisa mais difícil aqui é a necessidade de lidar com exceções dentro de cada lambda. Teria sido ótimo para a API ter sobrecargas UncheckedIOException para cada método IO. Com os ajudantes para fazer isso, pode-se escrever:

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

Usando lambdas (Java 8+)

opção não recursiva para excluir todos os arquivos na pasta atual que são mais antigos do que N dias (ignora subpastas):

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
        }
    });
}

opção recursiva, que atravessa sub-pastas e exclui todos os arquivos que são mais antigos que N dias:

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

Aqui está a versão do Java 8 usando o Time API. Ele foi testado e usado em nosso projeto:

    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

Outra abordagem com o Apache commons-io e 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

Você pode obter a data de criação do arquivo usando o NIO, seguindo o caminho:

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

Mais sobre isso pode ser encontrado aqui: http://docs.Oracle.com/javase/tutorial/essential/io/fileAttr.html

2
vikasing

Aqui está o código para excluir arquivos que não são modificados desde seis meses e também criar o arquivo de log.

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

Precisa apontar um bug na primeira solução listada, x * 24 * 60 * 60 * 1000 maximiza o valor int se x for grande. Então, precisa lançá-lo para um valor longo

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

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

Usando arquivos Java NIO com lambdas & Commons IO

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

Listar todos os arquivos e diretórios encontrados:

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

Ou apague arquivos encontrados com FileUtils :

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