2013-02-23 4 views
26

Как узнать, когда был создан файл с помощью java, поскольку я хочу удалить файлы старше определенного периода времени, в настоящее время я удаляю все файлы в каталоге, но это не идеально :Удалить файлы старше x дней

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

Выше мой текущий код, я пытаюсь теперь добавить, если заявление в том, что будут удалены только файлы старше чем, скажем, через неделю.

РЕДАКТИРОВАТЬ:

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

Добавление цикла в настоящее время.

EDIT

Я заметил, во время тестирования кода выше, я получаю Последнее изменение в:

INFO: Date Modified : 1361635382096 

Как следует закодировать, если петля сказать, если он старше 7 дней удалить его, когда он находится в вышеуказанном формате?

ответ

37

Вы можете использовать File.lastModified() для получения последнего измененного времени файла/каталога.

Может использоваться как это:

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

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

который удаляет файлы старше x (ан int) дней.

+0

Спасибо :) заглянет в него – user2065929

+0

, он даст последнее измененное время, а не время создания файла. – Arpit

+0

Thats fine, никакие модификации не могут быть внесены в файл после его создания никто не может его редактировать :) – user2065929

2

Вы можете получить дату создания файла с использованием NIO, следуя путь:

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

Подробнее об этом можно найти здесь: http://docs.oracle.com/javase/tutorial/essential/io/fileAttr.html

+0

'BasicFileAttributes' доступен только с java 7. Вы не можете использовать его с версиями java 6 или более ранних версий. –

21

Commons IO имеет встроенную поддержку для фильтрации файлов по возрасту с его AgeFileFilter. Ваш DeleteFiles может просто выглядеть следующим образом:

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: Чтобы использовать значение, как указано в вашем редактирования, определить thresholdDate как:

Date tresholdDate = new Date(1361635382096L); 
+0

Обновлено, чтобы показать, как обрабатывать значение, указанное в вашем редактировании. –

+1

Есть ли способ объединить AgeFileFilter с другим фильтром, например, NameFileFilter? – NathanChristie

+0

@NathanChristie см. [AndFileFilter] (http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/filefilter/AndFileFilter.html) и [OrFileFilter] (http: // commons .apache.org/proper/commons-io/apidocs/org/apache/commons/io/filefilter/OrFileFilter.html) – maxb3k

5

Использование Apache Utils, вероятно, самый простой. Вот самое простое решение, которое я мог бы придумать.

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 
} 
+1

Стоит также отметить, что вы можете использовать миллисекунды для создания AgeFileFilter, как этот «новый AgeFileFilter (System.currentTimeMillis() - AGE_LIMIT_MILLIS), где AGE_LIMIT_MILLIS можно сказать 24 * 60 * 60 * 1000L в течение 24 часов. –

+0

@MattC Это имеет какое-то влияние как исключение из памяти, если я использую его для каталога с 2 или 3 миллионами записей? – diwa

+0

@ Diwa Да, я предполагаю, что вы можете столкнуться с проблемами памяти, если у вас есть миллионы файлов. FileUtils создает java.util.LinkedList, а затем возвращает итератор этого списка. – MattC

8

Пример использования Java-8 в Time API

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

спасибо вам помогли. –

3

Для JDK 8 решения с использованием как NIO файловых потоков и 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 
      } 
     }); 

Sucky здесь является необходимость обработки исключения в каждой лямбда. Было бы замечательно, если бы API имел UncheckedIOException перегрузки для каждого метода ввода-вывода.С помощникам сделать это можно было бы написать:

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

} 
-1

Использование Apache Commons-IO и Joda:

 if (FileUtils.isFileOlder(f, DateTime.now().minusDays(30).toDate())) { 
      f.delete(); 
     } 
0

нужно указать на ошибку в первом решении перечисленных, х * 24 * 60 * 60 * 1000 будет превышать значение int, если x велико. Поэтому нужно, чтобы привести его к долгосрочной стоимости

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

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

Другой подход с Apache Commons-IO и 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... 
     } 
    } 
} 
0

Вот код, чтобы удалить файлы, которые не изменяются с шести месяцев & также создать журнальный файл.

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

Более полезно объяснить те части, которые OP не понимает, а не предоставлять им большую часть кода, который делает примерно то, что они хотят. Взгляните на принятый ответ здесь, у него гораздо меньше кода, чем у вас, но больше объяснений, и он решил вопрос лаконично. – SuperBiasedMan

1

Использование лямбды (Java 8+)

Non рекурсивный вариант, чтобы удалить все файлы в текущей папке, которые старше N дней (игнорирует вложенные папки):

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

Рекурсивная опция, которая перемещает подпапки и удаляет все файлы, которые старше N дней:

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

Использование Java NIO файлов с лямбды & Commons IO

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

Список всех найденных файлов и каталогов:

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

или удалить найденные файлы с FileUtils:

Files.newDirectoryStream(Paths.get("."), p -> (time - p.toFile().lastModified()) < maxdiff) 
.forEach(p -> FileUtils.deleteQuietly(p.toFile())); 
Смежные вопросы