如何在码头做家务?

How to do housekeeping in jetty?

我们让用户上传一些图像文件到我们的网络服务器。这些文件在上传 10-15 分钟后就没有用了。有没有办法自动删除这些文件,例如创建 15 分钟后名称中包含 'expire' 的所有图像文件?

我认为 Jetty 没有内置的功能。 您可以创建一种 GarbageCollector class 并使用 ScheduledExecutorService:

计划删除文件
public class GarbageCollector {
    private ScheduledExecutorService service = Executors.newScheduledThreadPool(1);

    public void scheduleFileDeletion(Path path) {
        service.schedule(() -> {
            try {
                Files.delete(path);
            } catch (IOException ignored) {
            }
        }, 15, TimeUnit.MINUTES);
    }
}

正如 mlapeyre 所说,码头上没有这样的东西。看看Guavas cache.

我猜这样的东西就可以了:

Cache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .removalListener(DELETE_FILES_LISTENER)
       .build();

您刚刚回答了自己的问题 - 获取名称中包含单词 "expire" 并在当前时间之前 15 分钟修改的所有文件并删除它们。

这是代码。效率不高但很简单:

File dir=new File(".");
String []expiredFiles=dir.list(new FilenameFilter() {
    @Override
    public boolean accept(File dir, String name) {
        return (name.contains("expired")&& new File(dir,name).lastModified()<System.currentTimeMillis()-15*60*1000);                
    }
});
for(String file:expiredFiles){
    new File(dir,file).delete();
}

您可以 运行 每 15 分钟左右。或者,更简单的方法,运行 当每个请求都被回答并关闭但线程尚未停止时它。例如,在您关闭响应对象上的输出流之后。它不会占用太多资源,尤其是当线程启动且仍在 运行ning 时。

创建模型 class 来存储有关上传图片的信息,例如 imagePathuploadedTime

class UploadedImage {
    private Path imagePath;
    private long uploadedTime;
    public UploadedImage(Path imagePath, long uploadedTime) {
        this.imagePath = imagePath;
        this.uploadedTime = uploadedTime;
    }
    public Path getImagePath() {
        return imagePath;
    }
    public long getUploadedTime() {
        return uploadedTime;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final UploadedImage other = (UploadedImage) obj;
        if (!Objects.equals(this.imagePath, other.imagePath)) {
            return false;
        }
        if (this.uploadedTime != other.uploadedTime) {
            return false;
        }
        return true;
    }
}

为每次上传图片创建一个UploadedImage对象,并将它们存储在全局ArrayList中。

//...
ArrayList<UploadedImage> imageBucket = new ArrayList<>();
//...

public synchronized void uploadingImage(Path imagePath, long uploadedTime){         
     imageBucket.add(new UploadeImage(imagePath, uploadedTime));
}

并准备一个线程来执行如下文件的删除。

    boolean deletionOff = false;
    new Thread(new Runnable() {
    private final long IMAGE_LIFE_TIME = 1000 * 60 * 15;//fifteen minutes
    @Override
    public void run() {
        while (!deletionOff) {
            //this fore-each will retrieve objects from OLDEST to NEWEST
            for (UploadedImage uploadedImage : imageBucket) {
                 //finds the elapsed time since the upload of this image
                long timeElapsed = System.currentTimeMillis() - uploadedImage.getUploadedTime();
                if (timeElapsed >= IMAGE_LIFE_TIME) {
                    //following commands will execute only if the image is eligible to delete
                    try {
                        Files.delete(uploadedImage.getImagePath());
                    } catch (IOException ex) {
                        //
                    } finally {
                        imageBucket.remove(uploadedImage);
                    }
                } else {
                    //this block will execute when IMAGE_LIFE_TIME is
                    //bigger than the elapsed time which means the
                    //selected image only have 
                    //(IMAGE_LIFE_TIME - timeElapsed) of time to stay alive 
                    //NOTE :
                    //there is no need to check the next UploadedImage
                    //objects as they were added to the list after the
                    //currently considering UploadedImage object, 
                    //which is still has some time to stay alive                           
                    try {
                        Thread.sleep(IMAGE_LIFE_TIME - timeElapsed);
                        break;
                    } catch (InterruptedException ex) {
                        //
                    }
                }
            }
        }
    }
}).start();

我基本上使用 cron 触发器在我的网络服务器中设置了 quartz 调度程序

这份工作看起来更像是这样

public static void deleteFilesOlderThanNdays(int daysBack, String dirWay, org.apache.commons.logging.Log log) {

    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);
                }
            }
        }
    } else {
        log.warn("Files were not deleted, directory " + dirWay + " does'nt exist!");
    }
}

参考:http://www.coderanch.com/t/384581/java/java/Delete-Files-Older-days