特定の期間よりも古いファイルを削除したいので、Javaを使用してファイルが作成された時期を知るにはどうすればよいですか?現在、ディレクトリ内のすべてのファイルを削除していますが、これは理想的ではありません:
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();
}
}
上記は私の現在のコードです。1週間以上経過したファイルのみを削除するifステートメントを追加しようとしています。
編集:
@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();
}
}
ループを追加します。
編集
上記のコードをテストしているときに、最後に変更されたものを取得しました:
INFO: Date Modified : 1361635382096
7日以上経過している場合にifループをコーディングするにはどうすればよいですか?
File.lastModified()
を使用して、ファイル/ディレクトリの最終変更時刻を取得できます。
次のように使用できます。
long diff = new Date().getTime() - file.lastModified();
if (diff > x * 24 * 60 * 60 * 1000) {
file.delete();
}
x
(int
)日より古いファイルを削除します。
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);
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);
}
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
}
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
}
}
});
}
NIOファイルストリームとJSR-310の両方を使用するJDK 8ソリューションの場合
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
}
});
ここで厄介なことは、各ラムダ内で例外を処理する必要があることです。 APIがIOメソッドごとに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);
}
}
}
Java 8バージョン。プロジェクトでテストされ、使用されています。
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();
}
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...
}
}
}
NIOを使用してファイルの作成日を取得できます。次の方法があります。
BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
System.out.println("creationTime: " + attrs.creationTime());
詳細については、こちらをご覧ください: http://docs.Oracle.com/javase/tutorial/essential/io/fileAttr.html
以下は、6か月間変更されていないファイルを削除し、ログファイルを作成するコードです。
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();
}
}
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()));
リストされている最初のソリューションのバグを指摘する必要があります。xが大きい場合、x * 24 * 60 * 60 * 1000はint値を最大にします。したがって、長い値にキャストする必要があります
long diff = new Date().getTime() - file.lastModified();
if (diff > (long) x * 24 * 60 * 60 * 1000) {
file.delete();
}
Apache commons-ioおよびjodaの使用:
if ( FileUtils.isFileOlder(f, DateTime.now().minusDays(30).toDate()) ) {
f.delete();
}