task-149: 临时文件时间元数据补缺(TempFileMetadata 创建/修改/访问时间与大小读取,mtime 回退不改变清理语义,IO 错误容忍)+ 8 条测试

This commit is contained in:
2026-09-02 06:08:50 +08:00
parent 383ec544e1
commit dd569edc66
3 changed files with 168 additions and 1 deletions
@@ -118,7 +118,8 @@ public class LocalTempCleanupService {
}
private boolean isExpired(File file, Instant expireBefore) {
return Instant.ofEpochMilli(file.lastModified()).isBefore(expireBefore);
// 以 mtime 近似最后访问(TempFileMetadata 回退语义,与现状一致)
return TempFileMetadata.lastAccessTime(file).isBefore(expireBefore);
}
private boolean isDirectoryEmpty(File directory) {
@@ -0,0 +1,57 @@
package com.nanri.aiimage.modules.file.service;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Instant;
/**
* 临时文件时间元数据读取(task-149)。
*
* 创建/最后修改/大小显式读取;最后访问时间无独立记录表,以 mtime 回退
* (与既有 LocalTempCleanupService 清理语义一致,不改变文件语义)。
* 属性读取失败或文件缺失时回退 mtime/0,不抛 IO 异常(清理路径不得被阻断)。
*/
public final class TempFileMetadata {
private TempFileMetadata() {
}
/** 创建时间;属性不可读时回退到最后修改时间。 */
public static Instant creationTime(File file) {
if (file == null || !file.isFile()) {
return lastModified(file);
}
try {
BasicFileAttributes attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
return attrs.creationTime().toInstant();
} catch (IOException ex) {
return lastModified(file);
}
}
/** 最后修改时间(mtime)。 */
public static Instant lastModified(File file) {
if (file == null) {
return Instant.EPOCH;
}
return Instant.ofEpochMilli(file.lastModified());
}
/**
* 最后访问时间:无独立访问记录表,以 mtime 回退
* (清理判据与现状一致:mtime 近似最后访问)。
*/
public static Instant lastAccessTime(File file) {
return lastModified(file);
}
/** 文件大小(字节);文件缺失时为 0。 */
public static long size(File file) {
if (file == null || !file.isFile()) {
return 0L;
}
return file.length();
}
}