Pozwalamy użytkownikom na przesyłanie plików graficznych na nasz serwer WWW. Pliki te nie są przydatne 10-15 minut po przesłaniu. Czy istnieje sposób automatycznego usuwania tych plików, np. wszystkie pliki graficzne, które mają "wygasły" w nazwie 15 minut po ich utworzeniu?Jak zrobić porządek w pomoście?
Odpowiedz
I w zasadzie konfiguracja kwarcowy scheduler wewnątrz mojego serwera WWW z wyzwalaczem cron
a praca wyglądała bardziej lub jak to
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!");
}
}
Ref: http://www.coderanch.com/t/384581/java/java/Delete-Files-Older-days
Nie sądzę, że pomost ma wbudowaną funkcję do tego. Można utworzyć rodzaj klasy GarbageCollector i zaplanować usunięcie pliku przy użyciu 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);
}
}
nie ma czegoś takiego w molo, jak mlapeyre mówi. Spójrz na Guavas cache.
Coś w tym rade, myślę:
Cache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(DELETE_FILES_LISTENER)
.build();
po prostu odpowiedział na swoje pytanie - pobranie wszystkich plików ze słowem „wygaśnie” w nazwie i modyfikowane 15 minut przed godzina prąd i je usunąć .
Oto kod. To nie jest wydajne, ale proste:
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();
}
Możesz uruchomić go co 15 minut. Lub, bardziej proste podejście, uruchom go, gdy każde żądanie zostanie odebrane i zamknięte, ale wątek nie zostanie zatrzymany. Na przykład tuż po zamknięciu strumienia wyjściowego w obiekcie odpowiedzi. Nie wymaga wiele zasobów, zwłaszcza gdy wątek jest uruchomiony i nadal działa.
Właściwie powinieneś uruchomić go jak każdą minutę :) Po prostu utwórz 'ServletContextListener', który będzie zarządzał cyklem życia' ScheduledExecutorService' i zaplanował prace porządkowe uruchamiane co minutę. –
Utwórz klasę modelu do przechowywania informacji o przesyłaniu obrazów, takich jak imagePath
i .
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;
}
}
Utwórz obiekt UploadedImage dla każdego obrazu przesyłanego i zapisuj go w globalnej tablicy ArrayList.
//...
ArrayList<UploadedImage> imageBucket = new ArrayList<>();
//...
public synchronized void uploadingImage(Path imagePath, long uploadedTime){
imageBucket.add(new UploadeImage(imagePath, uploadedTime));
}
Przygotuj wątek do usunięcia plików, takich jak poniższe.
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();
dlaczego nie wykorzystać pamięć podręczną i przechowuj bajty obrazu bezpośrednio w pamięci podręcznej. Ustaw czas eksmisji/wygaśnięcia na zapis (brak dostępu) na 10-15 minut, a pamięć podręczna automatycznie zajmie się obrazem. Wszelkie wyszukiwania dla obrazu są odbierane bezpośrednio z pamięci podręcznej (o ile wpis nie wygasł) –