1 32 package org.jruby.util; 33 34 import java.io.BufferedInputStream ; 35 import java.io.BufferedOutputStream ; 36 import java.io.FileNotFoundException ; 37 import java.io.IOException ; 38 import java.io.InputStream ; 39 import java.io.OutputStream ; 40 import java.io.RandomAccessFile ; 41 import java.nio.channels.FileChannel ; 42 43 import org.jruby.Ruby; 44 import org.jruby.RubyIO; 45 46 51 public class IOHandlerSeekable extends IOHandlerJavaIO { 52 protected RandomAccessFile file; 53 protected String path; 54 protected String cwd; 55 56 57 public IOHandlerSeekable(Ruby runtime, String path, IOModes modes) 58 throws IOException , InvalidValueException { 59 super(runtime); 60 61 this.path = path; 62 this.modes = modes; 63 this.cwd = runtime.getCurrentDirectory(); 64 JRubyFile theFile = JRubyFile.create(cwd,path); 65 66 if (theFile.exists()) { 67 if (modes.shouldTruncate()) { 68 if (!theFile.delete()) { 72 } 73 } 74 } else { 75 if (modes.isReadable() && !modes.isWriteable()) { 76 throw new FileNotFoundException (); 77 } 78 } 79 80 String javaMode = "r"; 83 if (modes.isWriteable()) { 84 javaMode += "w"; 85 } 86 87 file = new RandomAccessFile (theFile, javaMode); 89 isOpen = true; 90 91 if (modes.isAppendable()) { 92 seek(0, SEEK_END); 93 } 94 95 fileno = RubyIO.getNewFileno(); 98 } 99 100 private void reopen() throws IOException { 101 long pos = pos(); 102 103 String javaMode = "r"; 104 if (modes.isWriteable()) { 105 javaMode += "w"; 106 } 107 108 JRubyFile theFile = JRubyFile.create(cwd,path); 109 file.close(); 110 file = new RandomAccessFile (theFile, javaMode); 111 isOpen = true; 112 113 try { 114 seek(pos,SEEK_SET); 115 } catch(Exception e) { 116 throw new IOException (); 117 } 118 } 119 120 private void checkReopen() throws IOException { 121 if(file.length() != new java.io.File (path).length()) { 122 reopen(); 123 } 124 } 125 126 public ByteList getsEntireStream() throws IOException { 127 int c; 128 129 checkReopen(); 130 131 int left = (int)(file.length() - file.getFilePointer()); 132 byte[] buf = new byte[left]; 133 file.readFully(buf); 134 135 if (buf.length == 0) { 137 return null; 138 } 139 140 return new ByteList(buf,false); 141 } 142 143 144 public IOHandler cloneIOHandler() throws IOException , PipeException, InvalidValueException { 145 IOHandler newHandler = new IOHandlerSeekable(getRuntime(), path, modes); 146 147 newHandler.seek(pos(), SEEK_CUR); 148 149 return newHandler; 150 } 151 152 159 public void close() throws IOException , BadDescriptorException { 160 if (!isOpen()) { 161 throw new BadDescriptorException(); 162 } 163 164 isOpen = false; 165 166 file.close(); 167 } 168 169 174 public void flush() throws IOException , BadDescriptorException { 175 checkWriteable(); 176 177 } 179 180 183 public InputStream getInputStream() { 184 return new BufferedInputStream (new DataInputBridgeStream(file)); 185 } 186 187 190 public OutputStream getOutputStream() { 191 return new BufferedOutputStream (new DataOutputBridgeStream(file)); 192 } 193 194 199 public boolean isEOF() throws IOException , BadDescriptorException { 200 checkReadable(); 201 202 int c = file.read(); 203 if (c == -1) { 204 return true; 205 } 206 file.seek(file.getFilePointer() - 1); 207 return false; 208 } 209 210 213 public int pid() { 214 return -1; 216 } 217 218 222 public long pos() throws IOException { 223 checkOpen(); 224 225 return file.getFilePointer(); 226 } 227 228 public void resetByModes(IOModes newModes) throws IOException , InvalidValueException { 229 if (newModes.isAppendable()) { 230 seek(0L, SEEK_END); 231 } else if (newModes.isWriteable()) { 232 rewind(); 233 } 234 } 235 236 241 public void rewind() throws IOException , InvalidValueException { 242 seek(0, SEEK_SET); 243 } 244 245 250 public void seek(long offset, int type) throws IOException , InvalidValueException { 251 checkOpen(); 252 253 try { 255 switch (type) { 256 case SEEK_SET: 257 file.seek(offset); 258 break; 259 case SEEK_CUR: 260 file.seek(file.getFilePointer() + offset); 261 break; 262 case SEEK_END: 263 file.seek(file.length() + offset); 264 break; 265 } 266 } catch (IOException e) { 267 throw new InvalidValueException(); 268 } 269 } 270 271 274 public void sync() throws IOException { 275 file.getFD().sync(); 276 } 278 279 public ByteList sysread(int number) throws IOException , BadDescriptorException { 280 if (!isOpen()) { 281 throw new IOException ("File not open"); 282 } 283 checkReadable(); 284 byte[] buf = new byte[number]; 285 int read = 0; 286 int n; 287 while(read < number) { 288 n = file.read(buf,read,number-read); 289 if(n == -1) { 290 if(read == 0) { 291 throw new java.io.EOFException (); 292 } else { 293 break; 294 } 295 } 296 read += n; 297 } 298 299 return new ByteList(buf,0,read,false); 300 } 301 302 305 public int sysread() throws IOException { 306 return file.read(); 307 } 308 309 314 public int syswrite(ByteList buf) throws IOException , BadDescriptorException { 315 getRuntime().secure(4); 316 checkWriteable(); 317 318 if (buf == null || buf.realSize == 0) { 320 return 0; 321 } 322 323 file.write(buf.bytes,0,buf.realSize); 324 325 if (isSync()) { 326 sync(); 327 } 328 329 return buf.realSize; 330 } 331 332 337 public int syswrite(int c) throws IOException , BadDescriptorException { 338 getRuntime().secure(4); 339 checkWriteable(); 340 341 file.write(c); 342 343 if (isSync()) { 344 sync(); 345 } 346 347 return 1; 348 } 349 350 public void truncate(long newLength) throws IOException { 351 file.setLength(newLength); 352 } 353 354 public FileChannel getFileChannel() { 355 return file.getChannel(); 356 } 357 } 358 | Popular Tags |