1 package org.columba.core.io; 2 3 import java.io.File ; 4 import java.io.FileInputStream ; 5 import java.io.FileNotFoundException ; 6 import java.io.FileOutputStream ; 7 import java.io.IOException ; 8 import java.io.InputStream ; 9 import java.io.ObjectInputStream ; 10 import java.io.ObjectOutputStream ; 11 import java.io.Serializable ; 12 import java.util.ArrayList ; 13 import java.util.Collections ; 14 import java.util.Comparator ; 15 import java.util.Date ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 19 public class StreamCache { 20 21 public static final long DEFAULT_SIZE = 10 * 1024 * 1024; 23 public static final String FIFO_FILE = ".fifo"; 24 25 private File dir; 26 27 private List <CacheEntry> fifo; 28 29 private long actSize; 30 31 private long maxSize; 32 33 public StreamCache(File directory) { 34 this(directory, DEFAULT_SIZE); 35 } 36 37 public StreamCache(File directory, long maxSize) { 38 dir = directory; 39 if (!dir.exists()) { 40 if (!dir.mkdirs()) { 41 throw new RuntimeException (dir.toString() 42 + " could not be created!"); 43 } 44 } else { 45 try { 47 restore(); 48 } catch (IOException e) { 49 } 51 } 52 actSize = 0; 53 54 if (fifo == null) { 56 fifo = new ArrayList <CacheEntry>(100); 57 } 58 59 this.maxSize = maxSize; 60 } 61 62 public InputStream passiveAdd(Object key, InputStream in) 63 throws IOException { 64 File streamFile = new File (dir.getAbsoluteFile() + File.separator 65 + key.toString() + ".cache"); 66 return new StreamCacheCopyStream(in, key, streamFile, this); 67 } 68 69 public void activeAdd(Object key, InputStream in) throws IOException { 70 File streamFile = new File (dir.getAbsoluteFile() + File.separator 71 + key.toString() + ".cache"); 72 StreamUtils.streamCopy(in, new FileOutputStream (streamFile)); 73 add(key, streamFile); 74 } 75 76 void add(Object key, File out) { 77 fifo.add(new CacheEntry(key, out)); 78 79 actSize += out.length(); 80 81 Comparator _myComperator = new Comparator () { 82 83 public int compare(Object arg0, Object arg1) { 84 Date a = ((CacheEntry) arg0).lastAccess; 85 Date b = ((CacheEntry) arg1).lastAccess; 86 87 if (a.before(b)) 88 return 1; 89 if (a.after(b)) 90 return -1; 91 return 0; 92 } 93 94 }; 95 Collections.sort(fifo, _myComperator); 96 97 ensureMaxSize(); 98 } 99 100 private void ensureMaxSize() { 101 while (actSize > maxSize) { 102 CacheEntry entry = fifo.remove(fifo.size() - 1); 103 actSize -= entry.file.length(); 104 entry.file.delete(); 105 } 106 } 107 108 public InputStream get(Object key) { 109 Iterator it = fifo.iterator(); 110 111 while (it.hasNext()) { 112 CacheEntry c = (CacheEntry) it.next(); 113 if (c.key.equals(key)) { 114 try { 115 return c.createStream(); 116 } catch (FileNotFoundException e) { 117 it.remove(); 118 actSize -= c.file.length(); 119 } 120 } 121 } 122 123 return null; 124 } 125 126 public long getActSize() { 127 return actSize; 128 } 129 130 public void clear() { 131 Iterator it = fifo.iterator(); 132 133 while (it.hasNext()) { 134 CacheEntry c = (CacheEntry) it.next(); 135 if (!c.file.delete()) { 136 c.file.deleteOnExit(); 138 } 139 it.remove(); 140 } 141 142 actSize = 0; 143 } 144 145 public void persist() throws IOException { 146 File file = new File (dir.getAbsoluteFile() + File.separator + FIFO_FILE); 147 ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream ( 148 file)); 149 out.writeObject(fifo); 150 out.close(); 151 } 152 153 public void restore() throws IOException { 154 File file = new File (dir.getAbsoluteFile() + File.separator + FIFO_FILE); 155 try { 156 fifo = (List <CacheEntry>) new ObjectInputStream (new FileInputStream (file)) 157 .readObject(); 158 } catch (ClassNotFoundException e) { 159 } 161 } 162 163 public long getMaxSize() { 164 return maxSize; 165 } 166 167 public void setMaxSize(long maxSize) { 168 this.maxSize = maxSize; 169 ensureMaxSize(); 170 } 171 } 172 173 @SuppressWarnings ({"serial","serial"}) class CacheEntry implements Serializable { 174 Date lastAccess; 175 176 Object key; 177 178 File file; 179 180 public CacheEntry(Object key, File file) { 181 this.key = key; 182 this.file = file; 183 this.lastAccess = new Date (); 184 } 185 186 public InputStream createStream() throws FileNotFoundException { 187 this.lastAccess = new Date (); 188 return new FileInputStream (file); 189 } 190 191 194 public File getFile() { 195 return file; 196 } 197 198 202 public void setFile(File file) { 203 this.file = file; 204 } 205 206 209 public Object getKey() { 210 return key; 211 } 212 213 217 public void setKey(Object key) { 218 this.key = key; 219 } 220 221 224 public Date getLastAccess() { 225 return lastAccess; 226 } 227 228 232 public void setLastAccess(Date lastAccess) { 233 this.lastAccess = lastAccess; 234 } 235 } | Popular Tags |