1 18 package org.apache.batik.ext.awt.image.codec; 19 20 import java.io.File ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.RandomAccessFile ; 24 25 39 public final class FileCacheSeekableStream extends SeekableStream { 40 41 42 private InputStream stream; 43 44 45 private File cacheFile; 46 47 48 private RandomAccessFile cache; 49 50 51 private int bufLen = 1024; 52 53 54 private byte[] buf = new byte[bufLen]; 55 56 57 private long length = 0; 58 59 60 private long pointer = 0; 61 62 63 private boolean foundEOF = false; 64 65 73 public FileCacheSeekableStream(InputStream stream) 74 throws IOException { 75 this.stream = stream; 76 this.cacheFile = File.createTempFile("jai-FCSS-", ".tmp"); 77 cacheFile.deleteOnExit(); 78 this.cache = new RandomAccessFile (cacheFile, "rw"); 79 } 80 81 87 private long readUntil(long pos) throws IOException { 88 if (pos < length) { 90 return pos; 91 } 92 if (foundEOF) { 94 return length; 95 } 96 97 long len = pos - length; 98 cache.seek(length); 99 while (len > 0) { 100 int nbytes = stream.read(buf, 0, (int)Math.min(len, bufLen)); 103 if (nbytes == -1) { 104 foundEOF = true; 105 return length; 106 } 107 108 cache.setLength(cache.length() + nbytes); 109 cache.write(buf, 0, nbytes); 110 len -= nbytes; 111 length += nbytes; 112 } 113 114 return pos; 115 } 116 117 122 public boolean canSeekBackwards() { 123 return true; 124 } 125 126 132 public long getFilePointer() { 133 return pointer; 134 } 135 136 146 public void seek(long pos) throws IOException { 147 if (pos < 0) { 148 throw new IOException (PropertyUtil.getString("FileCacheSeekableStream0")); 149 } 150 pointer = pos; 151 } 152 153 165 public int read() throws IOException { 166 long next = pointer + 1; 167 long pos = readUntil(next); 168 if (pos >= next) { 169 cache.seek(pointer++); 170 return cache.read(); 171 } else { 172 return -1; 173 } 174 } 175 176 224 public int read(byte[] b, int off, int len) throws IOException { 225 if (b == null) { 226 throw new NullPointerException (); 227 } 228 if ((off < 0) || (len < 0) || (off + len > b.length)) { 229 throw new IndexOutOfBoundsException (); 230 } 231 if (len == 0) { 232 return 0; 233 } 234 235 long pos = readUntil(pointer + len); 236 237 len = (int)Math.min(len, pos - pointer); 239 if (len > 0) { 240 cache.seek(pointer); 241 cache.readFully(b, off, len); 242 pointer += len; 243 return len; 244 } else { 245 return -1; 246 } 247 } 248 249 255 public void close() throws IOException { 256 super.close(); 257 cache.close(); 258 cacheFile.delete(); 259 } 260 } 261 | Popular Tags |