package be.nikiroo.utils;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
+import be.nikiroo.utils.streams.MarkableFileInputStream;
+
/**
* A generic cache system, with special support for {@link URL}s.
* <p>
* @return the number of cleaned items
*/
public int clean(boolean onlyOld) {
- return clean(onlyOld, dir);
- }
-
- /**
- * Clean the cache (delete the cached items) in the given cache directory.
- *
- * @param onlyOld
- * only clean the files that are considered too old for stable
- * resources
- * @param cacheDir
- * the cache directory to clean
- *
- * @return the number of cleaned items
- */
- private int clean(boolean onlyOld, File cacheDir) {
long ms = System.currentTimeMillis();
tracer.trace("Cleaning cache from old files...");
- int num = doClean(onlyOld, cacheDir);
+ int num = clean(onlyOld, dir, -1);
- tracer.trace("Cache cleaned in " + (System.currentTimeMillis() - ms)
- + " ms");
+ tracer.trace(num + "cache items cleaned in "
+ + (System.currentTimeMillis() - ms) + " ms");
return num;
}
/**
- * Actual work done for {@link Cache#clean(boolean, File)}.
+ * Clean the cache (delete the cached items) in the given cache directory.
*
* @param onlyOld
* only clean the files that are considered too old for stable
* resources
* @param cacheDir
* the cache directory to clean
+ * @param limit
+ * stop after limit files deleted, or -1 for unlimited
*
* @return the number of cleaned items
*/
- private int doClean(boolean onlyOld, File cacheDir) {
+ private int clean(boolean onlyOld, File cacheDir, int limit) {
int num = 0;
File[] files = cacheDir.listFiles();
if (files != null) {
for (File file : files) {
+ if (limit >= 0 && num >= limit) {
+ return num;
+ }
+
if (file.isDirectory()) {
- num += doClean(onlyOld, file);
+ num += clean(onlyOld, file, limit);
+ file.delete(); // only if empty
} else {
if (!onlyOld || isOld(file, true)) {
if (file.delete()) {
if (cached.exists() && cached.isFile()
&& (allowTooOld || !isOld(cached, stable))) {
try {
- return new MarkableFileInputStream(new FileInputStream(cached));
+ return new MarkableFileInputStream(cached);
} catch (FileNotFoundException e) {
return null;
}
* @param uniqueID
* a unique ID used to locate the cached resource
*
+ * @return the number of bytes written
+ *
* @throws IOException
* in case of I/O error
*/
- public void save(InputStream in, String uniqueID) throws IOException {
+ public long save(InputStream in, String uniqueID) throws IOException {
File cached = getCached(uniqueID);
cached.getParentFile().mkdirs();
- save(in, cached);
+ return save(in, cached);
}
/**
* @param url
* the {@link URL} used to locate the cached resource
*
+ * @return the number of bytes written
+ *
* @throws IOException
* in case of I/O error
*/
- public void save(InputStream in, URL url) throws IOException {
+ public long save(InputStream in, URL url) throws IOException {
File cached = getCached(url);
- save(in, cached);
+ return save(in, cached);
}
/**
* @param cached
* the cached {@link File} to save to
*
+ * @return the number of bytes written
+ *
* @throws IOException
* in case of I/O error
*/
- private void save(InputStream in, File cached) throws IOException {
- clean(true);
- IOUtils.write(in, cached);
+ private long save(InputStream in, File cached) throws IOException {
+ // We want to force at least an immediate SAVE/LOAD to work for some
+ // workflows, even if we don't accept cached files (times set to "0"
+ // -- and not "-1" or a positive value)
+ clean(true, dir, 10);
+ cached.getParentFile().mkdirs(); // in case we deleted our own parent
+ long bytes = IOUtils.write(in, cached);
+ return bytes;
}
/**