View Javadoc
1 /* Reattore HTTP Server 2 3 Copyright (C) 2002 Michael Hope <michaelh@juju.net.nz> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 $Id: ChannelFileSource.java,v 1.13 2003/02/22 04:29:52 michaelh Exp $ 20 */ 21 22 package juju.reattore.io.impl; 23 24 import java.io.*; 25 import java.nio.ByteBuffer; 26 import java.nio.channels.*; 27 28 import juju.reattore.io.*; 29 30 /*** A byte source that serves from a file using channels. Implemented 31 by reading the whole file into a byte buffer. 32 33 @todo Minor: Cannot handle > 4GB files 34 @todo Doesn't implement get() for > readSize files 35 */ 36 public class ChannelFileSource 37 implements FileSource, CachableSource, BulkByteSource { 38 39 private Cache cache; 40 41 private File file; 42 private FileChannel fch; 43 private int size; 44 private int readSize = 64 * 1024; 45 46 private ByteBuffer bb; 47 private boolean oversized; 48 private boolean firstRead = true; 49 50 private static final int CHECK_INTERVAL = 5; 51 52 private long stamp; 53 private int checkIn = CHECK_INTERVAL; 54 55 /*** Create a new source around the given file. 56 57 @param file The file to wrap around. 58 @throws IOException if the file cannot be opened. 59 */ 60 public ChannelFileSource(File file) 61 throws IOException { 62 63 this.file = file; 64 65 stamp = file.lastModified(); 66 67 FileInputStream fin = new FileInputStream(file); 68 fch = fin.getChannel(); 69 70 size = (int)fch.size(); 71 } 72 73 private void setup() { 74 if (bb == null) { 75 oversized = size > readSize; 76 bb = ByteBufferPool.allocate(oversized ? readSize : size); 77 } 78 } 79 80 private void read() 81 throws IOException { 82 83 setup(); 84 85 if (firstRead || oversized) { 86 bb.clear(); 87 fch.read(bb); 88 89 bb.flip(); 90 } 91 92 firstRead = false; 93 } 94 95 /*** Test method that changes the maximum size a file may be before 96 it is chunked into parts. 97 98 @param to The maximum size in bytes. 99 */ 100 public void setReadSize(int to) { 101 this.readSize = to; 102 } 103 104 /*** @see BulkByteSource */ 105 public ByteBuffer getBulk() 106 throws IOException { 107 108 read(); 109 return bb; 110 } 111 112 /*** @see ByteSource */ 113 public int get() 114 throws IOException { 115 116 read(); 117 assert oversized == false; 118 119 return bb.get(); 120 } 121 122 /*** @see ByteSource */ 123 public int get(byte[] into, int offset, int length) 124 throws IOException { 125 126 read(); 127 assert oversized == false; 128 129 if (length > bb.remaining()) { 130 length = bb.remaining(); 131 } 132 133 bb.get(into, offset, length); 134 135 return length; 136 } 137 138 /*** @see ByteSource */ 139 public int remaining() 140 throws IOException { 141 142 setup(); 143 144 if (oversized) { 145 return (int)(size - fch.position()); 146 } 147 else { 148 read(); 149 return bb.remaining(); 150 } 151 } 152 153 /*** @see CachableSource */ 154 public void release() { 155 if (fch != null) { 156 try { 157 fch.close(); 158 } 159 catch (IOException ex) { 160 /* Drop */ 161 } 162 finally { 163 fch = null; 164 } 165 } 166 if (bb != null) { 167 ByteBufferPool.release(bb); 168 bb = null; 169 } 170 } 171 172 /*** @see Source */ 173 public void dispose() { 174 if (cache != null && cache.onClose(this) == false) { 175 /* The cache took us back */ 176 } 177 else { 178 release(); 179 } 180 } 181 182 /*** @see CachableSource */ 183 public void rewind() { 184 setup(); 185 186 if (oversized) { 187 } 188 else { 189 bb.rewind(); 190 } 191 } 192 193 /*** @see CachableSource 194 */ 195 public boolean isExpired() { 196 if (oversized) { 197 return true; 198 } 199 else if ((--checkIn) == 0) { 200 checkIn = CHECK_INTERVAL; 201 return file.lastModified() != stamp; 202 } 203 else { 204 return false; 205 } 206 } 207 208 /*** @see CachableSource */ 209 public void setCacheCallback(Cache ch) { 210 this.cache = ch; 211 } 212 }

This page was automatically generated by Maven