6

我想要一些 Java 代码来删除超过 N 天的文件。

这是我的尝试,但它并不完全正确。

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 
    {
    }
}

是否有一些简单的代码可以删除目录中超过 N 天的文件?

4

7 回答 7

12

尝试使用Calendar -Class 代替:

 Calendar cal = Calendar.getInstance();  
 cal.add(Calendar.DAY_OF_MONTH, daysBack * -1);  
 long purgeTime = cal.getTimeInMillis();   

或者试试这个解决方案

你的天数结束了24吗?如果是这样,你有一个溢出问题。

如果天数为25,则值为:

25 * 24 * 60 * 60 * 1000

数学值为2160000000。但是,这大于Integer.MAX_VALUE,因此值溢出到 -12516353。因此,吹扫时间将在未来,并且永远不会满足。大于 的值25只会使问题变得更糟;甚至有可能溢出非常糟糕,以至于乘法再次导致正值导致可能清除所有文件。

修复很简单:

  1. 声明daysBacklong
  2. 投到daysBack一个long

    long purgeTime = System.currentTimeMillis() - ((long)daysBack * 24 * 60 * 60 * 1000);  
    
  3. 在计算中使用显式长文字:

    long purgeTime = System.currentTimeMillis() - (daysBack * 24L * 60L * 60L * 1000L); 
    

对于所有三个解决方案,第一个和/或第二个操作数是 long 的事实将整个结果变成一个 long,从而允许 value2160000000不溢出。

于 2011-07-28T22:57:31.103 回答
7

我使用这个简单的代码片段来删除超过 N 天的文件

在此代码段中,删除基于文件上次修改的日期时间

daysBack = 删除超过 N 天的文件
dirWay = 包含文件的目录

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

谢谢

于 2015-02-23T12:47:48.830 回答
2

用于删除目录中超过 N 天的文件的 Java 程序:

对于您不小心用它擦除硬盘驱动器计算机,我概不负责。不要运行它,除非您了解它的作用以及它为什么这样做。如果您不小心对根目录或某些敏感目录运行此文件,旧文件将被永久删除。

该 Java 程序将收集所有文件的列表, C:\Users\penguins其中包含文本:MyLogFile_在其名称中。它查看lastModified()每个文件的日期,并以毫秒为单位查看它的年龄,如果差异大于指定的天数(以毫秒为单位的 8 天),则删除该文件。

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

要让此代码为您工作,您需要:

  1. 将 dir 设置为要从中删除文件的目录。
  2. 将 numDays 变量设置为文件被删除的天数。
  3. MyLogFile_单词设置为要删除的文件的签名。将其设置为空白以查看所有文件。

当此代码使您失败时:

如果系统日期更改为未来或过去,(或一些奇怪的闰秒、时区更改或系统日期编辑)发生,那么这可能会继续删除横冲直撞。如果文件上的日期被人为操纵,那么这可能会导致删除横冲直撞。如果文件的权限过于严格,则不会删除该文件。

于 2014-08-21T14:15:50.047 回答
0

您可以使用 file.lastModified() 方法

像下面这样的东西。

文件 file = new File("YOUR_FOLDER_PATH");

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

 if (diff > Z * 24 * 60 * 60 * 1000) {
  file.delete();
 }
于 2014-02-06T22:11:07.223 回答
0

如果您的意思是“大约 30 天前”,则其他答案是正确的。但是如果你的意思是更精确,那么你应该注意时区。如果您的意思是一整天,请注意一天中的时间。

如果要使用UTC /GMT,请使用此时区对象:DateTimeZone.UTC

这是一些使用Joda-Time 3.2 库的示例代码。

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

转储到控制台...</p>

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

运行时……</p>

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
于 2014-02-07T06:23:08.213 回答
0

使用 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);
        }
}
于 2019-07-15T15:42:33.367 回答
0

我正在研究类似的东西,我已经包装了一些 java.nio.file.Files 方法,以便拥有一个干净的基于 Java 8 流的方法。

我的需要是 7 天,但您可以根据自己的需要进行调整:

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

我将包装的方法放在一个 utils 类中:

公共类 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);
}

}

请注意,我正在使用 Lombok 插件中的 @SneakyThrows。如果您不使用它,您可以实现它或使用 try/catch 来威胁异常。

于 2021-03-07T23:00:28.660 回答