001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * Created on Oct 1, 2009 021 * Author: Andreas Prlic 022 * 023 */ 024 025package org.biojava.utils.io; 026 027import java.io.ByteArrayInputStream; 028import java.io.File; 029import java.io.FileInputStream; 030import java.io.IOException; 031import java.io.InputStream; 032 033/** Provides a cache for storing multiple small files in memory. Can be used to e.g cache gzip compressed PDB files for avoiding disk IO bottlenecks. 034 * 035 * @author Andreas Prlic. 036 * 037 */ 038public class FlatFileCache { 039 040 private static FlatFileCache me ; 041 042 private static SoftHashMap cache; 043 public static FlatFileCache getInstance() { 044 045 if ( me == null){ 046 me = new FlatFileCache(); 047 } 048 049 return me; 050 } 051 052 // no public constructor; 053 private FlatFileCache(){ 054 cache = new SoftHashMap(0); 055 } 056 057 058 public static void addToCache(String key, File fileToCache){ 059 //System.out.println("storing " + key + " on file cache (cache size: " + cache.size() + ")"); 060 try { 061 InputStream is = new FileInputStream(fileToCache); 062 // Get the size of the file 063 long length = fileToCache.length(); 064 065 // You cannot create an array using a long type. 066 // It needs to be an int type. 067 // Before converting to an int type, check 068 // to ensure that file is not larger than Integer.MAX_VALUE. 069 if (length > Integer.MAX_VALUE) { 070 // File is too large 071 } 072 073 // Create the byte array to hold the data 074 byte[] bytes = new byte[(int)length]; 075 076 // Read in the bytes 077 int offset = 0; 078 int numRead = 0; 079 while (offset < bytes.length 080 && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { 081 offset += numRead; 082 } 083 084 // Ensure all the bytes have been read in 085 if (offset < bytes.length) { 086 throw new IOException("Could not completely read file "+fileToCache.getName()); 087 } 088 089 // Close the input stream and return bytes 090 is.close(); 091 092 cache.put(key,bytes); 093 } catch (Exception e){ 094 e.printStackTrace(); 095 } 096 } 097 098 public static InputStream getInputStream(String key){ 099 //System.out.println("returning " + key + " from file cache (cache size: " + cache.size() + ")"); 100 byte[] bytes = (byte[])cache.get(key); 101 if ( bytes == null) 102 return null; 103 104 return new ByteArrayInputStream(bytes); 105 106 } 107 108 public int size() { 109 if ( cache != null) 110 return cache.size(); 111 else 112 return -1; 113 } 114 115 public void clear(){ 116 cache.clear(); 117 } 118 119 public static void destroy(){ 120 me.clear(); 121 me = null; 122 } 123 124}