Java Delete files older than N days
I would like some Java code to Delete files older than N days.
Here is my attempt, but it doesn't work quite right.
public void deleteFilesOlderThanNdays(final int daysBack, final String dirWay) {
System.out.println(dirWay);
System.out.println(daysBack);
final File directory = new File(dirWay);
if(directory.exists()){
System.out.println(" Directory Exists");
final File[] listFiles = directory.listFiles();
final long purgeTime =
System.currentTimeMillis() - (daysBack * 24 * 60 * 60 * 1000);
System.out.println("System.currentTimeMillis " +
System.currentTimeMillis());
System.out.println("purgeTime " + purgeTime);
for(File listFile : listFiles) {
System.out.println("Length : "+ listFiles.length);
System.out.println("listFile.getName() : " +listFile.getName());
System.out.println("listFile.lastModified() :"+
listFile.lastModified());
if(listFile.lastModified() < purgeTime) {
System.out.println("Inside File Delete")开发者_运维百科;
}
}
}
else
{
}
}
Is there some simple code to delete files older than N days in a directory?
Try to use the Calendar-Class instead:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, daysBack * -1);
long purgeTime = cal.getTimeInMillis();
Or try this solution:
Is your number of days over 24
? If so, you have an overflow problem.
If the number of days is 25
, the value will be:
25 * 24 * 60 * 60 * 1000
The mathematical value is 2160000000
. However, this is larger than Integer.MAX_VALUE
, and therefore the value overflows to
-12516353
. As a result, the purge time will be in the future, and will never be met. Values larger than 25
will only make the problem worse; it's even possible the overflow is so bad that the multiplication results in a positive value again leading to perhaps purge all files.
The fix is easy:
- declare
daysBack
as along
cast
daysBack
to along
long purgeTime = System.currentTimeMillis() - ((long)daysBack * 24 * 60 * 60 * 1000);
Use explicit long literals inside the calculation:
long purgeTime = System.currentTimeMillis() - (daysBack * 24L * 60L * 60L * 1000L);
For all three solutions, the fact that the first and/or second operand is a long turns the entire result into a long, allowing a value of 2160000000
without overflowing.
I use this simple code snippet to delete files older than N days
In this snippet deletion is based on file last-modified datetime
daysBack = Delete files older than N days
dirWay = Directory that contain files
public static void deleteFilesOlderThanNdays(int daysBack, String dirWay) {
File directory = new File(dirWay);
if(directory.exists()){
File[] listFiles = directory.listFiles();
long purgeTime = System.currentTimeMillis() - (daysBack * 24 * 60 * 60 * 1000);
for(File listFile : listFiles) {
if(listFile.lastModified() < purgeTime) {
if(!listFile.delete()) {
System.err.println("Unable to delete file: " + listFile);
}
}
}
}
}
Thanks
Java program to delete files in a directory older than N days:
I am not responsible for you accidentally erasing your hard drive computer with this. Don't run it unless you understand what it does and why it does it. If you accidentally run this file against root, or some sensitive directory, old files will be permanently erased.
This Java program will gather a list of all the files in C:\Users\penguins
that contain the text: MyLogFile_
in its name. It looks at the lastModified()
date of each file, and sees how old it is in milliseconds, if the difference is greater than the number of days specified (8 days in milliseconds), then the file is deleted.
import java.io.File;
import java.util.*;
class Runner{
public static void main(String[] args){
long numDays = 8; //this needs to be a long.
//WARNING! OLD FILES IN THIS DIRECTORY WILL BE DELETED.
String dir = "C:\\Users\\penguins";
//IF YOU ACCIDENTALLY POINT THIS TO C:\\Windows or other sensitive
//directory (and run it) you will be living in the house of pain.
File directory = new File(dir);
File[] fList = directory.listFiles();
if (fList != null){
for (File file : fList){
if (file.isFile() &&
file.getName().contains("MyLogFile_")){
long diff = new Date().getTime() - file.lastModified();
long cutoff = (numDays * (24 * 60 * 60 * 1000));
if (diff > cutoff) {
file.delete();
}
}
}
}
}
}
To get this code to work for you, you need to:
- Set the dir to the directory you want to delete files from.
- set the numDays variable to the number of days past which files get deleted.
- Set the
MyLogFile_
word to the signature of files you want to delete. Set it to blank to look at all files.
When this code will fail you:
If the system Date is changed to future or past, (or some weird leap-second, timezone change, or system date edit) happens, then this may go on a deleting rampage. If dates on the files are artificially manipulated, then this may go on a deleting rampage. If permissions are too restrictive on the files, the file won't be deleted.
If you mean "approximately 30 days ago", the other answers are correct. But if you mean to be more precise, then you should pay attention to time zone. And if you mean whole days, pay attention to time-of-day.
If you want to use UTC/GMT, use this time zone object: DateTimeZone.UTC
Here is some example code using the Joda-Time 3.2 library.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Oslo" );
DateTime now = new DateTime( timeZone );
DateTime cutoff = now.minusDays( 30 ).withTimeAtStartOfDay();
DateTime fileCreationDateTime = new DateTime( 2014, 1, 2, 3, 4, 5, timeZone );
boolean fileShouldBeDeleted = fileCreationDateTime.isBefore( cutoff );
DateTime file2CreationDateTime = now.minusMinutes( 1 );
boolean file2ShouldBeDeleted = file2CreationDateTime.isBefore( cutoff );
Dump to console…
System.out.println( "now: " + now );
System.out.println( "cutoff: " + cutoff );
System.out.println( "fileCreationDateTime: " + fileCreationDateTime );
System.out.println( "fileShouldBeDeleted: " + fileShouldBeDeleted );
System.out.println( "file2CreationDateTime: " + file2CreationDateTime );
System.out.println( "file2ShouldBeDeleted: " + file2ShouldBeDeleted );
When run…
now: 2014-02-07T07:20:32.898+01:00
cutoff: 2014-01-08T00:00:00.000+01:00
fileCreationDateTime: 2014-01-02T03:04:05.000+01:00
fileShouldBeDeleted: true
file2CreationDateTime: 2014-02-07T07:19:32.898+01:00
file2ShouldBeDeleted: false
You can use file.lastModified() method
Some thing like below.
File file = new File("YOUR_FOLDER_PATH");
long diff = new Date().getTime() - file.lastModified();
if (diff > Z * 24 * 60 * 60 * 1000) {
file.delete();
}
A code snippet using Java 8
public static void deleteFilesOlderThanNdays(int daysAgo, String destDir) throws IOException {
Instant instantDaysAgo = Instant.from(ZonedDateTime.now().minusDays(daysAgo));
BiPredicate<Path, BasicFileAttributes> fileIsOlderThanNDays =
(path, attr) -> attr.lastModifiedTime().compareTo( FileTime.from(instantDaysAgo)) < 0 ;
List<Path> filesToDelete = (List) Files.find(Paths.get(destDir), 1 , fileIsOlderThanNDays )
.collect(Collectors.toList());
for (Path path : filesToDelete) {
Files.delete(path);
}
}
I was researching something similar and I've wrapped some java.nio.file.Files methods in order to have a clean Java 8 stream based method.
My need was for 7 days period but you can adapt it to your need:
public void cleanFilesOlderThan7Days() {
try {
Files.walk(Paths.get("temp/raw_reports"))
.filter(Files::isRegularFile)
.filter(FilesUtils::isOlderThan7Days)
.forEach(FilesUtils::delete);
} catch (IOException e) {
log.error("Could not clean old files", e);
}
}
I put the wrapped methods in an utils class:
public class FilesUtils {
@SneakyThrows
public static boolean isOlderThan7Days(java.nio.file.Path path) {
FileTime lastModifiedTime = Files.getLastModifiedTime(path);
Duration interval = Duration.between(lastModifiedTime.toInstant(), Instant.now());
return interval.toDays() > 7;
}
@SneakyThrows
public static void delete(java.nio.file.Path path) {
Files.delete(path);
}
}
Notice I am using @SneakyThrows from Lombok plugin. If you are not using it you can either implement it or use try/catch to threat the exceptions.
精彩评论