Search code examples
javacachingfileinputstream

Caching FileInputStream


In my program I am repeatedly reading a number of files like this:

String myLetter = "CoverSheet.rtf"; // actually has a full path
FileInputStream in = new FileInputStream(myLetter);
letterSection.importRtfDocument(in);
in.close();

Because there are many small files which are components to add to the document with importRtfDocument, and thousands of letters to generate in a run, the processing is quite slow.

The importRtfDocument method comes from a library I'm using, and needs to be given a FileInputStream. This is where I'm stumped. I tried a few things like declaring a FileInputStream for each file in the class and keeping them open - but reset() isn't supported.

I have looked at other similar questions like this one:

How to Cache InputStream for Multiple Use

However, none seem to address my problem, to wit, how can I cache a FileInputStream?


Solution

  • I normally create my own pool to cache files. Just consider following simple code :

    class CachedPool {
        private Map<URI, CachedFile> pool = new HashMap<>();
    
        public CachedPool(){
        }
    
        public <T> T getResource(URI uri) {
            CachedFile file;
            if(pool.containsKey(uri)){
                file = pool.get(uri);
            } else {
                file = new CachedFile(uri);   // Injecting point to add resources
                pool.put(uri, file);
            }
            return file.getContent();
        }
    }
    
    class CachedFile {
        private URI uri;
        private int counter;
        private Date cachedTime;
        private Object content;
    
        public CachedFile(URL uri){
            this.url = uri;
            this.content = uri.toURL().getContent();
            this.cachedTime = new Date();
            this.counter = 0;
        }
    
        public <T> T getContent(){
            counter++;
            return (T) content;
        }
    
        /** Override equals() and hashCode() **/
        /** Write getters for all instance variables **/
    }
    

    You can use counter of CachedFile to remove the files that are rarely being used after a certain time period or when heap memory is very low.