如何在码头做家务?
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 来存储有关上传图片的信息,例如 imagePath
和 uploadedTime
。
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
我们让用户上传一些图像文件到我们的网络服务器。这些文件在上传 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 来存储有关上传图片的信息,例如 imagePath
和 uploadedTime
。
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