tags:

views:

88

answers:

2

Hi,

I'm trying to write many files to a directory, and when the directory reaches X number of files, I want the least recently accessed file to be deleted before writing the new file. I don't really want to roll my own solution to this because I'd imagine someone else has already done this before. Are there existing solutions to this? Note this is for a windows application.

This is related to my question http://stackoverflow.com/questions/3732582/java-ehcache-disk-store, but I'm asking this question separately since now I'm focusing on a file caching solution.

Thanks, Jeff

A: 

I would roll my own, because the problem sounds so easy that writing it yourself is probably easier than trying to learn and adopt an existing library :-)

It it's a low number of files and / or your cash is accessed from multiple processes, call the following method before writing a file:

void deleteOldFiles(String dir, long maxFileCount) {
    while (true) {
        File oldest = null;
        long oldestTime = 0;
        File[] list = new File(dir).listFiles();
        if (list.length < maxFileCount) {
            break;
        }
        for (File f : list) {
            long m = f.lastModified();
            if (oldest == null || oldestTime > m) {
                oldestTime = m;
                oldest = f;
            }
        }
        oldest.delete();
    }
}

If you only access the cache from one process, you could write something more efficient using LinkedHashMap or LinkedHashSet.

Update

Check the number of files instead of the total file size.

Thomas Mueller
I use something similar myself but the code you posted limits the total size of all files in the directory, not the number of files.
Grodriguez
Updated to check the file count instead of size. Hm, now my and your code are very similar...
Thomas Mueller
Indeed. What is the canonical way to proceed in this situation? Should I delete my answer (as I posted it later)? Please advise.
Grodriguez
I have no idea... There is no "team answer" option...
Thomas Mueller
A: 

You can try this before creating a new file:

void deleteOldFiles(String dir, int maxFiles) {
    File fdir = new File(dir);
    while (true) {
        // Check number of files. Also do nothing if maxFiles == 0
        File[] files = fdir.listFiles();
        if (maxFiles == 0 || files.length < maxFiles)
            break;

        // Delete oldest
        File oldest = files[0];
        for (int i = 1; i < files.length; i++) {
            if (files[i].lastModified() < oldest.lastModified()) {
                oldest = files[i];
            }
        }
        oldest.delete();
    }
}

This would not be efficient for a large number of files, though. In that case I would keep a list of files in the directory, sorted by creation time.

Although all of this gets into the 'roll my own category'...

Grodriguez
I think this would throw a NullPointerException if maxFiles is 0 and there are no files in the directory yet.
Thomas Mueller
maxFiles == 0 doesn't seem a very useful case but if you insist.. :-)
Grodriguez
Hm, now if maxFiles is 0 and there are files in the directory, it would never delete any files...
Thomas Mueller
If maxFiles == 0, then writing any file at all to the directory makes no sense, hence this is a corner case anyway. So, why bothering deleting old files?
Grodriguez
Unfortunately, I am working with a large number of files, so iterating isn't feasible like this. I've tentatively implemented a LinkedHashMap based solution, so we'll see how that works out...
Jeff Storey
@Jeff, I imagined this (large number of files) would indeed be the case from your other question (http://stackoverflow.com/questions/3732582/java-ehcache-disk-store), but I thought this could still be of some help, so I posted it just in case.
Grodriguez
Thanks, appreciated.
Jeff Storey