java - temporales - Eliminar archivos anteriores a x días
script para borrar temporales de windows (12)
¿Cómo puedo saber cuándo se creó un archivo usando java, ya que deseo eliminar archivos anteriores a cierto período de tiempo, actualmente estoy borrando todos los archivos en un directorio, pero esto no es 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();
}
}
Arriba está mi código actual, estoy tratando de agregar una declaración if que solo borrará los archivos anteriores a una 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();
}
}
Agregar un bucle ahora
EDITAR
Me di cuenta mientras probaba el código anterior que recibí la última modificación en:
INFO: Date Modified : 1361635382096
¿Cómo debo codificar el ciclo if para decir si es anterior a 7 días borrarlo cuando está en el formato anterior?
Ejemplo utilizando la API de tiempo 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);
}
Usando lambdas (Java 8+)
Opción no recursiva para eliminar todos los archivos en la carpeta actual que son anteriores a N días (ignora las subcarpetas):
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
}
});
}
Opción recursiva, que atraviesa subcarpetas y elimina todos los archivos que tienen más de N días:
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
}
}
});
}
Usar archivos Java NIO con lambdas y Commons IO
final long time = new Date().getTime();
// Only show files & directories older than 2 days
final long maxdiff = TimeUnit.DAYS.toMillis(2);
Lista de todos los archivos y directorios encontrados:
Files.newDirectoryStream(Paths.get("."), p -> (time - p.toFile().lastModified()) < maxdiff)
.forEach(System.out::println);
O elimine los archivos encontrados con FileUtils :
Files.newDirectoryStream(Paths.get("."), p -> (time - p.toFile().lastModified()) < maxdiff)
.forEach(p -> FileUtils.deleteQuietly(p.toFile()));
Aquí está el código para eliminar archivos que no se han modificado desde hace seis meses y también crear el archivo de registro.
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();
}
}
Es necesario señalar un error en la primera solución en la lista, x * 24 * 60 * 60 * 1000 maximizará el valor int si x es grande. Entonces, necesito convertirlo a un valor largo
long diff = new Date().getTime() - file.lastModified();
if (diff > (long) x * 24 * 60 * 60 * 1000) {
file.delete();
}
Otro enfoque con Apache commons-io y 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...
}
}
}
Para una solución JDK 8 que utiliza flujos de archivos NIO y 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
}
});
Lo sucky aquí es la necesidad de manejar excepciones dentro de cada lambda. Hubiera sido genial para la API tener sobrecargas UncheckedIOException
para cada método IO. Con ayudantes para hacer esto uno podría escribir:
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);
}
}
}
Puede obtener la fecha de creación del archivo usando NIO, a continuación se muestra el camino:
BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
System.out.println("creationTime: " + attrs.creationTime());
Se puede encontrar más información aquí: http://docs.oracle.com/javase/tutorial/essential/io/fileAttr.html
Puede usar File.lastModified()
para obtener la última hora modificada de un archivo / directorio.
Se puede usar así:
long diff = new Date().getTime() - file.lastModified();
if (diff > x * 24 * 60 * 60 * 1000) {
file.delete();
}
Que elimina archivos anteriores a x
(un int
) días.
Usando Apache commons-io y joda:
if ( FileUtils.isFileOlder(f, DateTime.now().minusDays(30).toDate()) ) {
f.delete();
}
Usar Apache utils es probablemente el más fácil. Aquí está la solución más simple que podría 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
}
Commons IO tiene soporte integrado para filtrar archivos por edad con su AgeFileFilter . Sus DeleteFiles
podrían verse así:
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();
}
}
Actualización: para usar el valor que se da en su edición, defina el thresholdDate
como:
Date tresholdDate = new Date(1361635382096L);