1 36 package org.columba.ristretto.io; 37 38 import java.io.File ; 39 import java.io.IOException ; 40 import java.io.RandomAccessFile ; 41 import java.nio.ByteBuffer ; 42 import java.nio.channels.FileChannel ; 43 import java.util.Timer ; 44 import java.util.TimerTask ; 45 46 55 public class FileSourceModel { 56 57 private File file; 58 private FileChannel channel; 59 private ByteBuffer buffer; 60 private int bufferStart; 61 private int references; 62 63 private CloseChannelTimerTask closeTask; 64 65 private static Timer timer = new Timer (); 67 68 private static final int BUFFERSIZE = 61440; private static final long CLOSE_DELAY = 2000; 71 72 78 public FileSourceModel( File file ) throws IOException { 79 this.file = file; 80 81 buffer = ByteBuffer.allocate( BUFFERSIZE ); 82 83 bufferStart = 0; 84 references = 0; 85 86 updateBufferFromFile(); 87 } 88 89 96 public char get( int pos ) throws IOException { 97 if( (pos < bufferStart) ) { 99 while( pos < bufferStart ) { 100 bufferStart -= (BUFFERSIZE / 2); 101 } 102 103 updateBufferFromFile(); 104 } else 105 if (pos >= bufferStart + BUFFERSIZE ) { 106 while( pos >= bufferStart + BUFFERSIZE ) { 107 bufferStart += (BUFFERSIZE / 2); 108 } 109 updateBufferFromFile(); 110 } 111 112 byte value = buffer.get( pos - bufferStart ); 115 int trueValue = (value & 0x080) + (value & 0x07F); 116 117 return (char) trueValue; 118 } 119 120 123 private void updateBufferFromFile() throws IOException { 124 if( channel == null ) { 125 channel = new RandomAccessFile ( file, "r" ).getChannel(); 126 } 127 128 buffer.clear(); 129 channel.read(buffer, bufferStart ); 130 131 restartCloseTimer(); 134 } 135 136 private void restartCloseTimer() { 137 if( closeTask != null ) closeTask.cancel(); 138 closeTask = new CloseChannelTimerTask(this); 139 timer.schedule(closeTask, CLOSE_DELAY); 140 } 141 142 148 public int length() throws IOException { 149 return (int) channel.size(); 150 } 151 152 157 public void incReferences() { 158 references++; 159 } 160 161 167 public void decReferences() { 168 references--; 169 if( references <= 0 ) { 170 try { 171 close(); 172 } catch (IOException e) { 173 e.printStackTrace(); 174 } 175 } 176 } 177 178 183 public void close() throws IOException { 184 if( channel != null) { 185 channel.close(); 186 channel = null; 187 } 188 } 189 190 193 public File getFile() { 194 return file; 195 } 196 197 } 198 199 200 class CloseChannelTimerTask extends TimerTask { 201 202 FileSourceModel model; 203 204 205 210 public CloseChannelTimerTask(FileSourceModel model) { 211 super(); 212 this.model = model; 213 } 214 217 public void run() { 218 try { 219 model.close(); 220 } catch (IOException e) { 221 } 222 } 223 } | Popular Tags |