Source for java.io.RandomAccessFile

   1: /* RandomAccessFile.java -- Class supporting random file I/O
   2:    Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10:  
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.io;
  40: 
  41: import gnu.java.nio.channels.FileChannelImpl;
  42: 
  43: import java.nio.channels.FileChannel;
  44: 
  45: /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
  46:  * "The Java Language Specification", ISBN 0-201-63451-1
  47:  * Status: Believe complete and correct to 1.1.
  48:  */
  49: 
  50: /**
  51:  * This class allows reading and writing of files at random locations.
  52:  * Most Java I/O classes are either pure sequential input or output.  This
  53:  * class fulfills the need to be able to read the bytes of a file in an
  54:  * arbitrary order.  In addition, this class implements the
  55:  * <code>DataInput</code> and <code>DataOutput</code> interfaces to allow
  56:  * the reading and writing of Java primitives.
  57:  *
  58:  * @author Aaron M. Renn (arenn@urbanophile.com)
  59:  * @author Tom Tromey (tromey@cygnus.com)
  60:  */
  61: public class RandomAccessFile implements DataOutput, DataInput, Closeable
  62: {
  63: 
  64:   // The underlying file.
  65:   private FileChannelImpl ch;
  66:   private FileDescriptor fd;
  67:   // The corresponding input and output streams.
  68:   private DataOutputStream out;
  69:   private DataInputStream in;
  70:   
  71:   
  72:   /**
  73:    * This method initializes a new instance of <code>RandomAccessFile</code>
  74:    * to read from the specified <code>File</code> object with the specified 
  75:    * access mode.   The access mode is either "r" for read only access or "rw" 
  76:    * for read-write access.
  77:    * <p>
  78:    * Note that a <code>SecurityManager</code> check is made prior to
  79:    * opening the file to determine whether or not this file is allowed to
  80:    * be read or written.
  81:    *
  82:    * @param file The <code>File</code> object to read and/or write.
  83:    * @param mode "r" for read only or "rw" for read-write access to the file
  84:    *
  85:    * @exception IllegalArgumentException If <code>mode</code> has an 
  86:    * illegal value
  87:    * @exception SecurityException If the requested access to the file 
  88:    * is not allowed
  89:    * @exception FileNotFoundException If the file is a directory, or 
  90:    * any other error occurs
  91:    */
  92:   public RandomAccessFile (File file, String mode)
  93:     throws FileNotFoundException
  94:   {
  95:     int fdmode;
  96:     if (mode.equals("r"))
  97:       fdmode = FileChannelImpl.READ;
  98:     else if (mode.equals("rw"))
  99:       fdmode = FileChannelImpl.READ | FileChannelImpl.WRITE;
 100:     else if (mode.equals("rws"))
 101:       {
 102:     fdmode = (FileChannelImpl.READ | FileChannelImpl.WRITE
 103:           | FileChannelImpl.SYNC);
 104:       }
 105:     else if (mode.equals("rwd"))
 106:       {
 107:     fdmode = (FileChannelImpl.READ | FileChannelImpl.WRITE
 108:           | FileChannelImpl.DSYNC);
 109:       }
 110:     else
 111:       throw new IllegalArgumentException ("invalid mode: " + mode);
 112: 
 113:     final String fileName = file.getPath();
 114: 
 115:     // The obligatory SecurityManager stuff
 116:     SecurityManager s = System.getSecurityManager();
 117:     if (s != null)
 118:       {
 119:         s.checkRead(fileName);
 120: 
 121:         if ((fdmode & FileChannelImpl.WRITE) != 0)
 122:           s.checkWrite(fileName);
 123:       }
 124: 
 125:     ch = FileChannelImpl.create(file, fdmode);
 126:     fd = new FileDescriptor(ch);
 127:     if ((fdmode & FileChannelImpl.WRITE) != 0)
 128:       out = new DataOutputStream (new FileOutputStream (fd));
 129:     else
 130:       out = null;
 131:     in = new DataInputStream (new FileInputStream (fd));
 132:   }
 133: 
 134:   /**
 135:    * This method initializes a new instance of <code>RandomAccessFile</code>
 136:    * to read from the specified file name with the specified access mode.
 137:    * The access mode is either "r" for read only access, "rw" for read
 138:    * write access, "rws" for synchronized read/write access of both
 139:    * content and metadata, or "rwd" for read/write access
 140:    * where only content is required to be synchronous.
 141:    * <p>
 142:    * Note that a <code>SecurityManager</code> check is made prior to
 143:    * opening the file to determine whether or not this file is allowed to
 144:    * be read or written.
 145:    *
 146:    * @param fileName The name of the file to read and/or write
 147:    * @param mode "r", "rw", "rws", or "rwd"
 148:    *
 149:    * @exception IllegalArgumentException If <code>mode</code> has an 
 150:    * illegal value
 151:    * @exception SecurityException If the requested access to the file 
 152:    * is not allowed
 153:    * @exception FileNotFoundException If the file is a directory or 
 154:    * any other error occurs
 155:    */
 156:   public RandomAccessFile (String fileName, String mode)
 157:     throws FileNotFoundException
 158:   {
 159:     this (new File(fileName), mode);
 160:   }
 161: 
 162:   /**
 163:    * This method closes the file and frees up all file related system
 164:    * resources.  Since most operating systems put a limit on how many files
 165:    * may be opened at any given time, it is a good idea to close all files
 166:    * when no longer needed to avoid hitting this limit
 167:    */
 168:   public void close () throws IOException
 169:   {
 170:     ch.close();
 171:   }
 172: 
 173:   /**
 174:    * This method returns a <code>FileDescriptor</code> object that 
 175:    * represents the native file handle for this file.
 176:    *
 177:    * @return The <code>FileDescriptor</code> object for this file
 178:    *
 179:    * @exception IOException If an error occurs
 180:    */
 181:   public final FileDescriptor getFD () throws IOException
 182:   {
 183:     synchronized (this)
 184:       {
 185:     if (fd == null)
 186:       fd = new FileDescriptor (ch);
 187:     return fd;
 188:       }
 189:   }
 190: 
 191:   /**
 192:    * This method returns the current offset in the file at which the next
 193:    * read or write will occur
 194:    *
 195:    * @return The current file position
 196:    *
 197:    * @exception IOException If an error occurs
 198:    */
 199:   public long getFilePointer () throws IOException
 200:   {
 201:     return ch.position();
 202:   }
 203: 
 204:   /**
 205:    * This method sets the length of the file to the specified length.
 206:    * If the currently length of the file is longer than the specified
 207:    * length, then the file is truncated to the specified length (the
 208:    * file position is set to the end of file in this case).  If the
 209:    * current length of the file is shorter than the specified length,
 210:    * the file is extended with bytes of an undefined value (the file
 211:    * position is unchanged in this case).
 212:    * <p>
 213:    * The file must be open for write access for this operation to succeed.
 214:    *
 215:    * @param newLen The new length of the file
 216:    *
 217:    * @exception IOException If an error occurs
 218:    */
 219:   public void setLength (long newLen) throws IOException
 220:   {
 221:     // FIXME: Extending a file should probably be done by one method call.
 222: 
 223:     // FileChannel.truncate() can only shrink a file.
 224:     // To expand it we need to seek forward and write at least one byte.
 225:     if (newLen < length())
 226:       ch.truncate (newLen);
 227:     else if (newLen > length())
 228:       {
 229:     long pos = getFilePointer();
 230:     seek(newLen - 1);
 231:     write(0);
 232:     seek(pos);
 233:       }
 234:   }
 235: 
 236:   /**
 237:    * This method returns the length of the file in bytes
 238:    *
 239:    * @return The length of the file
 240:    *
 241:    * @exception IOException If an error occurs
 242:    */
 243:   public long length () throws IOException
 244:   {
 245:     return ch.size();
 246:   }
 247: 
 248:   /**
 249:    * This method reads a single byte of data from the file and returns it
 250:    * as an integer.
 251:    *
 252:    * @return The byte read as an int, or -1 if the end of the file was reached.
 253:    *
 254:    * @exception IOException If an error occurs
 255:    */
 256:   public int read () throws IOException
 257:   {
 258:     return in.read();
 259:   }
 260: 
 261:   /**
 262:    * This method reads bytes from the file into the specified array.  The
 263:    * bytes are stored starting at the beginning of the array and up to 
 264:    * <code>buf.length</code> bytes can be read.
 265:    *
 266:    * @param buffer The buffer to read bytes from the file into
 267:    *
 268:    * @return The actual number of bytes read or -1 if end of file
 269:    *
 270:    * @exception IOException If an error occurs
 271:    */
 272:   public int read (byte[] buffer) throws IOException
 273:   {
 274:     return in.read (buffer);
 275:   }
 276: 
 277:   /**
 278:    * This methods reads up to <code>len</code> bytes from the file into the
 279:    * specified array starting at position <code>offset</code> into the array.
 280:    *
 281:    * @param buffer The array to read the bytes into
 282:    * @param offset The index into the array to start storing bytes
 283:    * @param len The requested number of bytes to read
 284:    *
 285:    * @return The actual number of bytes read, or -1 if end of file
 286:    *
 287:    * @exception IOException If an error occurs
 288:    */
 289:   public int read (byte[] buffer, int offset, int len) throws IOException
 290:   {
 291:     return in.read (buffer, offset, len);
 292:   }
 293: 
 294:   /**
 295:    * This method reads a Java boolean value from an input stream.  It does
 296:    * so by reading a single byte of data.  If that byte is zero, then the
 297:    * value returned is <code>false</code>  If the byte is non-zero, then
 298:    * the value returned is <code>true</code>
 299:    * <p>
 300:    * This method can read a <code>boolean</code> written by an object 
 301:    * implementing the
 302:    * <code>writeBoolean()</code> method in the <code>DataOutput</code> 
 303:    * interface.
 304:    *
 305:    * @return The <code>boolean</code> value read
 306:    *
 307:    * @exception EOFException If end of file is reached before reading the 
 308:    * boolean
 309:    * @exception IOException If any other error occurs
 310:    */
 311:   public final boolean readBoolean () throws IOException
 312:   {
 313:     return in.readBoolean ();
 314:   }
 315: 
 316:   /**
 317:    * This method reads a Java byte value from an input stream.  The value
 318:    * is in the range of -128 to 127.
 319:    * <p>
 320:    * This method can read a <code>byte</code> written by an object 
 321:    * implementing the 
 322:    * <code>writeByte()</code> method in the <code>DataOutput</code> interface.
 323:    *
 324:    * @return The <code>byte</code> value read
 325:    *
 326:    * @exception EOFException If end of file is reached before reading the byte
 327:    * @exception IOException If any other error occurs
 328:    *
 329:    * @see DataOutput
 330:    */
 331:   public final byte readByte () throws IOException
 332:   {
 333:     return in.readByte ();
 334:   }
 335: 
 336:   /**
 337:    * This method reads a Java <code>char</code> value from an input stream.  
 338:    * It operates by reading two bytes from the stream and converting them to 
 339:    * a single 16-bit Java <code>char</code>  The two bytes are stored most
 340:    * significant byte first (i.e., "big endian") regardless of the native
 341:    * host byte ordering. 
 342:    * <p>
 343:    * As an example, if <code>byte1</code> and <code>byte2</code> represent 
 344:    * the first
 345:    * and second byte read from the stream respectively, they will be
 346:    * transformed to a <code>char</code> in the following manner:
 347:    * <p>
 348:    * <code>(char)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
 349:    * <p>
 350:    * This method can read a <code>char</code> written by an object 
 351:    * implementing the
 352:    * <code>writeChar()</code> method in the <code>DataOutput</code> interface.
 353:    *
 354:    * @return The <code>char</code> value read 
 355:    *
 356:    * @exception EOFException If end of file is reached before reading the char
 357:    * @exception IOException If any other error occurs
 358:    *
 359:    * @see DataOutput
 360:    */
 361:   public final char readChar () throws IOException
 362:   {
 363:     return in.readChar();
 364:   }
 365: 
 366:   /**
 367:    * This method reads a Java double value from an input stream.  It operates
 368:    * by first reading a <code>logn</code> value from the stream by calling the
 369:    * <code>readLong()</code> method in this interface, then 
 370:    * converts that <code>long</code>
 371:    * to a <code>double</code> using the <code>longBitsToDouble</code> 
 372:    * method in the class <code>java.lang.Double</code>
 373:    * <p>
 374:    * This method can read a <code>double</code> written by an object 
 375:    * implementing the
 376:    * <code>writeDouble()</code> method in the <code>DataOutput</code> 
 377:    * interface.
 378:    *
 379:    * @return The <code>double</code> value read
 380:    *
 381:    * @exception EOFException If end of file is reached before reading 
 382:    * the double
 383:    * @exception IOException If any other error occurs
 384:    *
 385:    * @see java.lang.Double
 386:    * @see DataOutput
 387:    */
 388:   public final double readDouble () throws IOException
 389:   {
 390:     return in.readDouble ();
 391:   }
 392: 
 393:   /**
 394:    * This method reads a Java float value from an input stream.  It operates
 395:    * by first reading an <code>int</code> value from the stream by calling the
 396:    * <code>readInt()</code> method in this interface, then converts 
 397:    * that <code>int</code>
 398:    * to a <code>float</code> using the <code>intBitsToFloat</code> method in 
 399:    * the class <code>java.lang.Float</code>
 400:    * <p>
 401:    * This method can read a <code>float</code> written by an object 
 402:    * implementing the
 403:    * <code>writeFloat()</code> method in the <code>DataOutput</code> interface.
 404:    *
 405:    * @return The <code>float</code> value read
 406:    *
 407:    * @exception EOFException If end of file is reached before reading the float
 408:    * @exception IOException If any other error occurs
 409:    *
 410:    * @see java.lang.Float
 411:    * @see DataOutput
 412:    */
 413:   public final float readFloat () throws IOException
 414:   {
 415:     return in.readFloat();
 416:   }
 417: 
 418:   /**
 419:    * This method reads raw bytes into the passed array until the array is
 420:    * full.  Note that this method blocks until the data is available and
 421:    * throws an exception if there is not enough data left in the stream to
 422:    * fill the buffer
 423:    *
 424:    * @param buffer The buffer into which to read the data
 425:    *
 426:    * @exception EOFException If end of file is reached before filling the 
 427:    * buffer
 428:    * @exception IOException If any other error occurs
 429:    */
 430:   public final void readFully (byte[] buffer) throws IOException
 431:   {
 432:     in.readFully(buffer);
 433:   }
 434: 
 435:   /**
 436:    * This method reads raw bytes into the passed array <code>buf</code> 
 437:    * starting
 438:    * <code>offset</code> bytes into the buffer.  The number of bytes read 
 439:    * will be
 440:    * exactly <code>len</code>  Note that this method blocks until the data is 
 441:    * available and throws an exception if there is not enough data left in 
 442:    * the stream to read <code>len</code> bytes.
 443:    *
 444:    * @param buffer The buffer into which to read the data
 445:    * @param offset The offset into the buffer to start storing data
 446:    * @param count The number of bytes to read into the buffer
 447:    *
 448:    * @exception EOFException If end of file is reached before filling 
 449:    * the buffer
 450:    * @exception IOException If any other error occurs
 451:    */
 452:   public final void readFully (byte[] buffer, int offset, int count)
 453:     throws IOException
 454:   {
 455:     in.readFully (buffer, offset, count);
 456:   }
 457: 
 458:   /**
 459:    * This method reads a Java <code>int</code> value from an input stream
 460:    * It operates by reading four bytes from the stream and converting them to 
 461:    * a single Java <code>int</code>  The bytes are stored most
 462:    * significant byte first (i.e., "big endian") regardless of the native
 463:    * host byte ordering. 
 464:    * <p>
 465:    * As an example, if <code>byte1</code> through <code>byte4</code> 
 466:    * represent the first
 467:    * four bytes read from the stream, they will be
 468:    * transformed to an <code>int</code> in the following manner:
 469:    * <p>
 470:    * <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 24) + ((byte2 &amp; 0xFF) &lt;&lt; 16) + 
 471:    * ((byte3 &amp; 0xFF) &lt;&lt; 8) + (byte4 &amp; 0xFF)))</code>
 472:    * <p>
 473:    * The value returned is in the range of 0 to 65535.
 474:    * <p>
 475:    * This method can read an <code>int</code> written by an object 
 476:    * implementing the
 477:    * <code>writeInt()</code> method in the <code>DataOutput</code> interface.
 478:    *
 479:    * @return The <code>int</code> value read
 480:    *
 481:    * @exception EOFException If end of file is reached before reading the int
 482:    * @exception IOException If any other error occurs
 483:    *
 484:    * @see DataOutput
 485:    */
 486:   public final int readInt () throws IOException
 487:   {
 488:     return in.readInt();
 489:   }
 490: 
 491:   /**
 492:    * This method reads the next line of text data from an input stream.
 493:    * It operates by reading bytes and converting those bytes to 
 494:    * <code>char</code>
 495:    * values by treating the byte read as the low eight bits of the 
 496:    * <code>char</code>
 497:    * and using <code>0</code> as the high eight bits.  Because of this, it does
 498:    * not support the full 16-bit Unicode character set.
 499:    * <p>
 500:    * The reading of bytes ends when either the end of file or a line terminator
 501:    * is encountered.  The bytes read are then returned as a <code>String</code>
 502:    * A line terminator is a byte sequence consisting of either 
 503:    * <code>\r</code> <code>\n</code> or <code>\r\n</code>  These 
 504:    * termination charaters are
 505:    * discarded and are not returned as part of the string.
 506:    * <p>
 507:    * This method can read data that was written by an object implementing the
 508:    * <code>writeLine()</code> method in <code>DataOutput</code>
 509:    *
 510:    * @return The line read as a <code>String</code>
 511:    *
 512:    * @exception IOException If an error occurs
 513:    *
 514:    * @see DataOutput
 515:    */
 516:   public final String readLine () throws IOException
 517:   {
 518:     return in.readLine ();
 519:   }
 520: 
 521:   /**
 522:    * This method reads a Java long value from an input stream
 523:    * It operates by reading eight bytes from the stream and converting them to 
 524:    * a single Java <code>long</code>  The bytes are stored most
 525:    * significant byte first (i.e., "big endian") regardless of the native
 526:    * host byte ordering. 
 527:    * <p>
 528:    * As an example, if <code>byte1</code> through <code>byte8</code> 
 529:    * represent the first
 530:    * eight bytes read from the stream, they will be
 531:    * transformed to an <code>long</code> in the following manner:
 532:    * <p>
 533:    * <code>
 534:    * (long)((((long)byte1 &amp; 0xFF) &lt;&lt; 56) + (((long)byte2 &amp; 0xFF) &lt;&lt; 48) + 
 535:    * (((long)byte3 &amp; 0xFF) &lt;&lt; 40) + (((long)byte4 &amp; 0xFF) &lt;&lt; 32) + 
 536:    * (((long)byte5 &amp; 0xFF) &lt;&lt; 24) + (((long)byte6 &amp; 0xFF) &lt;&lt; 16) + 
 537:    * (((long)byte7 &amp; 0xFF) &lt;&lt; 8) + ((long)byte9 &amp; 0xFF)))</code>
 538:    * <p>
 539:    * The value returned is in the range of 0 to 65535.
 540:    * <p>
 541:    * This method can read an <code>long</code> written by an object 
 542:    * implementing the
 543:    * <code>writeLong()</code> method in the <code>DataOutput</code> interface.
 544:    *
 545:    * @return The <code>long</code> value read
 546:    *
 547:    * @exception EOFException If end of file is reached before reading the long
 548:    * @exception IOException If any other error occurs
 549:    *
 550:    * @see DataOutput
 551:    */
 552:   public final long readLong () throws IOException
 553:   {
 554:     return in.readLong();
 555:   }
 556: 
 557:   /**
 558:    * This method reads a signed 16-bit value into a Java in from the stream.
 559:    * It operates by reading two bytes from the stream and converting them to 
 560:    * a single 16-bit Java <code>short</code>  The two bytes are stored most
 561:    * significant byte first (i.e., "big endian") regardless of the native
 562:    * host byte ordering. 
 563:    * <p>
 564:    * As an example, if <code>byte1</code> and <code>byte2</code> 
 565:    * represent the first
 566:    * and second byte read from the stream respectively, they will be
 567:    * transformed to a <code>short</code> in the following manner:
 568:    * <p>
 569:    * <code>(short)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
 570:    * <p>
 571:    * The value returned is in the range of -32768 to 32767.
 572:    * <p>
 573:    * This method can read a <code>short</code> written by an object 
 574:    * implementing the
 575:    * <code>writeShort()</code> method in the <code>DataOutput</code> interface.
 576:    *
 577:    * @return The <code>short</code> value read
 578:    *
 579:    * @exception EOFException If end of file is reached before reading the value
 580:    * @exception IOException If any other error occurs
 581:    *
 582:    * @see DataOutput
 583:    */
 584:   public final short readShort () throws IOException
 585:   {
 586:     return in.readShort();
 587:   }
 588: 
 589:   /**
 590:    * This method reads 8 unsigned bits into a Java <code>int</code> value 
 591:    * from the 
 592:    * stream. The value returned is in the range of 0 to 255.
 593:    * <p>
 594:    * This method can read an unsigned byte written by an object implementing 
 595:    * the <code>writeUnsignedByte()</code> method in the 
 596:    * <code>DataOutput</code> interface.
 597:    *
 598:    * @return The unsigned bytes value read as a Java <code>int</code>
 599:    *
 600:    * @exception EOFException If end of file is reached before reading the value
 601:    * @exception IOException If any other error occurs
 602:    *
 603:    * @see DataOutput
 604:    */
 605:   public final int readUnsignedByte () throws IOException
 606:   {
 607:     return in.readUnsignedByte();
 608:   }
 609: 
 610:   /**
 611:    * This method reads 16 unsigned bits into a Java int value from the stream.
 612:    * It operates by reading two bytes from the stream and converting them to 
 613:    * a single Java <code>int</code>  The two bytes are stored most
 614:    * significant byte first (i.e., "big endian") regardless of the native
 615:    * host byte ordering. 
 616:    * <p>
 617:    * As an example, if <code>byte1</code> and <code>byte2</code> 
 618:    * represent the first
 619:    * and second byte read from the stream respectively, they will be
 620:    * transformed to an <code>int</code> in the following manner:
 621:    * <p>
 622:    * <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 8) + (byte2 &amp; 0xFF))</code>
 623:    * <p>
 624:    * The value returned is in the range of 0 to 65535.
 625:    * <p>
 626:    * This method can read an unsigned short written by an object implementing
 627:    * the <code>writeUnsignedShort()</code> method in the 
 628:    * <code>DataOutput</code> interface.
 629:    *
 630:    * @return The unsigned short value read as a Java <code>int</code>
 631:    *
 632:    * @exception EOFException If end of file is reached before reading the value
 633:    * @exception IOException If any other error occurs
 634:    */
 635:   public final int readUnsignedShort () throws IOException
 636:   {
 637:     return in.readUnsignedShort();
 638:   }
 639: 
 640:   /**
 641:    * This method reads a <code>String</code> from an input stream that 
 642:    * is encoded in
 643:    * a modified UTF-8 format.  This format has a leading two byte sequence
 644:    * that contains the remaining number of bytes to read.  This two byte
 645:    * sequence is read using the <code>readUnsignedShort()</code> method of this
 646:    * interface.
 647:    * <p>
 648:    * After the number of remaining bytes have been determined, these bytes
 649:    * are read an transformed into <code>char</code> values.  
 650:    * These <code>char</code> values
 651:    * are encoded in the stream using either a one, two, or three byte format.
 652:    * The particular format in use can be determined by examining the first
 653:    * byte read.  
 654:    * <p>
 655:    * If the first byte has a high order bit of 0 then
 656:    * that character consists on only one byte.  This character value consists
 657:    * of seven bits that are at positions 0 through 6 of the byte.  As an
 658:    * example, if <code>byte1</code> is the byte read from the stream, it would
 659:    * be converted to a <code>char</code> like so:
 660:    * <p>
 661:    * <code>(char)byte1</code>
 662:    * <p>
 663:    * If the first byte has <code>110</code> as its high order bits, then the 
 664:    * character consists of two bytes.  The bits that make up the character
 665:    * value are in positions 0 through 4 of the first byte and bit positions
 666:    * 0 through 5 of the second byte.  (The second byte should have 
 667:    * 10 as its high order bits).  These values are in most significant
 668:    * byte first (i.e., "big endian") order.
 669:    * <p>
 670:    * As an example, if <code>byte1</code> and <code>byte2</code> 
 671:    * are the first two bytes
 672:    * read respectively, and the high order bits of them match the patterns
 673:    * which indicate a two byte character encoding, then they would be
 674:    * converted to a Java <code>char</code> like so:
 675:    * <p>
 676:    * <code>(char)(((byte1 & 0x1F) << 6) | (byte2 & 0x3F))</code>
 677:    * <p>
 678:    * If the first byte has a <code>1110</code> as its high order bits, then the
 679:    * character consists of three bytes.  The bits that make up the character
 680:    * value are in positions 0 through 3 of the first byte and bit positions
 681:    * 0 through 5 of the other two bytes.  (The second and third bytes should
 682:    * have <code>10</code> as their high order bits).  These values are in most
 683:    * significant byte first (i.e., "big endian") order.
 684:    * <p>
 685:    * As an example, if <code>byte1</code> <code>byte2</code> 
 686:    * and <code>byte3</code> are the
 687:    * three bytes read, and the high order bits of them match the patterns
 688:    * which indicate a three byte character encoding, then they would be
 689:    * converted to a Java <code>char</code> like so:
 690:    * <p>
 691:    * <code>(char)(((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | 
 692:    * (byte3 & 0x3F))</code>
 693:    * <p>
 694:    * Note that all characters are encoded in the method that requires the
 695:    * fewest number of bytes with the exception of the character with the
 696:    * value of <code>&#92;u0000</code> which is encoded as two bytes.  This is 
 697:    * a  modification of the UTF standard used to prevent C language style
 698:    * <code>NUL</code> values from appearing in the byte stream.
 699:    * <p>
 700:    * This method can read data that was written by an object implementing the
 701:    * <code>writeUTF()</code> method in <code>DataOutput</code>
 702:    * 
 703:    * @return The <code>String</code> read
 704:    *
 705:    * @exception EOFException If end of file is reached before reading the 
 706:    * String
 707:    * @exception UTFDataFormatException If the data is not in UTF-8 format
 708:    * @exception IOException If any other error occurs
 709:    *
 710:    * @see DataOutput
 711:    */
 712:   public final String readUTF () throws IOException
 713:   {
 714:     return in.readUTF();
 715:   }
 716: 
 717:   /**
 718:    * This method sets the current file position to the specified offset 
 719:    * from the beginning of the file.  Note that some operating systems will
 720:    * allow the file pointer to be set past the current end of the file.
 721:    *
 722:    * @param pos The offset from the beginning of the file at which to set 
 723:    * the file pointer
 724:    *
 725:    * @exception IOException If an error occurs
 726:    */
 727:   public void seek (long pos) throws IOException
 728:   {
 729:     ch.position(pos);
 730:   }
 731: 
 732:   /**
 733:    * This method attempts to skip and discard the specified number of bytes 
 734:    * in the input stream.  It may actually skip fewer bytes than requested. 
 735:    * The actual number of bytes skipped is returned.  This method will not
 736:    * skip any bytes if passed a negative number of bytes to skip.
 737:    *
 738:    * @param numBytes The requested number of bytes to skip.
 739:    *
 740:    * @return The number of bytes actually skipped.
 741:    *
 742:    * @exception IOException If an error occurs.
 743:    */
 744:   public int skipBytes (int numBytes) throws IOException
 745:   {
 746:     if (numBytes < 0)
 747:       throw new IllegalArgumentException ("Can't skip negative bytes: " +
 748:                                           numBytes);
 749:     
 750:     if (numBytes == 0)
 751:       return 0;
 752:     
 753:     long oldPos = ch.position();
 754:     long newPos = oldPos + numBytes;
 755:     long size = ch.size();
 756:     if (newPos > size)
 757:       newPos = size;
 758:     ch.position(newPos);
 759:     return (int) (ch.position() - oldPos);
 760:   }
 761: 
 762:   /**
 763:    * This method writes a single byte of data to the file. The file must
 764:    * be open for read-write in order for this operation to succeed.
 765:    *
 766:    * @param oneByte The byte of data to write, passed as an int.
 767:    *
 768:    * @exception IOException If an error occurs
 769:    */
 770:   public void write (int oneByte) throws IOException
 771:   {
 772:     if (out == null)
 773:       throw new IOException("Bad file descriptor");
 774: 
 775:     out.write(oneByte);
 776:   }
 777: 
 778:   /**
 779:    * This method writes all the bytes in the specified array to the file.
 780:    * The file must be open read-write in order for this operation to succeed.
 781:    *
 782:    * @param buffer The array of bytes to write to the file
 783:    */
 784:   public void write (byte[] buffer) throws IOException
 785:   {
 786:     if (out == null)
 787:       throw new IOException("Bad file descriptor");
 788: 
 789:     out.write(buffer);
 790:   }
 791: 
 792:   /**
 793:    * This method writes <code>len</code> bytes to the file from the specified
 794:    * array starting at index <code>offset</code> into the array.
 795:    *
 796:    * @param buffer The array of bytes to write to the file
 797:    * @param offset The index into the array to start writing file
 798:    * @param len The number of bytes to write
 799:    *
 800:    * @exception IOException If an error occurs
 801:    */
 802:   public void write (byte[] buffer, int offset, int len) throws IOException
 803:   {
 804:     if (out == null)
 805:       throw new IOException("Bad file descriptor");
 806: 
 807:     out.write (buffer, offset, len);
 808:   }
 809: 
 810:   /**
 811:    * This method writes a Java <code>boolean</code> to the underlying output 
 812:    * stream. For a value of <code>true</code>, 1 is written to the stream.
 813:    * For a value of <code>false</code>, 0 is written.
 814:    *
 815:    * @param val The <code>boolean</code> value to write to the stream
 816:    *
 817:    * @exception IOException If an error occurs
 818:    */
 819:   public final void writeBoolean (boolean val) throws IOException
 820:   {
 821:     if (out == null)
 822:       throw new IOException("Bad file descriptor");
 823: 
 824:     out.writeBoolean(val);
 825:   }
 826: 
 827:   /**
 828:    * This method writes a Java <code>byte</code> value to the underlying
 829:    * output stream.
 830:    *
 831:    * @param val The <code>byte</code> to write to the stream, passed 
 832:    * as an <code>int</code>.
 833:    *
 834:    * @exception IOException If an error occurs
 835:    */
 836:   public final void writeByte (int val) throws IOException
 837:   {
 838:     if (out == null)
 839:       throw new IOException("Bad file descriptor");
 840: 
 841:     out.writeByte(val);
 842:   }
 843: 
 844:   /**
 845:    * This method writes a Java <code>short</code> to the stream, high byte
 846:    * first.  This method requires two bytes to encode the value.
 847:    *
 848:    * @param val The <code>short</code> value to write to the stream, 
 849:    * passed as an <code>int</code>.
 850:    *
 851:    * @exception IOException If an error occurs
 852:    */
 853:   public final void writeShort (int val) throws IOException
 854:   {
 855:     if (out == null)
 856:       throw new IOException("Bad file descriptor");
 857: 
 858:     out.writeShort(val);
 859:   }
 860: 
 861:   /**
 862:    * This method writes a single <code>char</code> value to the stream,
 863:    * high byte first.
 864:    *
 865:    * @param val The <code>char</code> value to write, passed as 
 866:    * an <code>int</code>.
 867:    *
 868:    * @exception IOException If an error occurs
 869:    */
 870:   public final void writeChar (int val) throws IOException
 871:   {
 872:     if (out == null)
 873:       throw new IOException("Bad file descriptor");
 874: 
 875:     out.writeChar(val);
 876:   }
 877: 
 878:   /**
 879:    * This method writes a Java <code>int</code> to the stream, high bytes
 880:    * first.  This method requires four bytes to encode the value.
 881:    *
 882:    * @param val The <code>int</code> value to write to the stream.
 883:    *
 884:    * @exception IOException If an error occurs
 885:    */
 886:   public final void writeInt (int val) throws IOException
 887:   {
 888:     if (out == null)
 889:       throw new IOException("Bad file descriptor");
 890: 
 891:     out.writeInt(val);
 892:   }
 893: 
 894:   /**
 895:    * This method writes a Java <code>long</code> to the stream, high bytes
 896:    * first.  This method requires eight bytes to encode the value.
 897:    *
 898:    * @param val The <code>long</code> value to write to the stream.
 899:    *
 900:    * @exception IOException If an error occurs
 901:    */
 902:   public final void writeLong (long val) throws IOException
 903:   {
 904:     if (out == null)
 905:       throw new IOException("Bad file descriptor");
 906: 
 907:     out.writeLong(val);
 908:   }
 909: 
 910:   /**
 911:    * This method writes a Java <code>float</code> value to the stream.  This
 912:    * value is written by first calling the method 
 913:    * <code>Float.floatToIntBits</code>
 914:    * to retrieve an <code>int</code> representing the floating point number,
 915:    * then writing this <code>int</code> value to the stream exactly the same
 916:    * as the <code>writeInt()</code> method does.
 917:    *
 918:    * @param val The floating point number to write to the stream.
 919:    *
 920:    * @exception IOException If an error occurs
 921:    *
 922:    * @see #writeInt(int)
 923:    */
 924:   public final void writeFloat (float val) throws IOException
 925:   {
 926:     if (out == null)
 927:       throw new IOException("Bad file descriptor");
 928: 
 929:     out.writeFloat(val);
 930:   }
 931: 
 932:   /**
 933:    * This method writes a Java <code>double</code> value to the stream.  This
 934:    * value is written by first calling the method 
 935:    * <code>Double.doubleToLongBits</code>
 936:    * to retrieve an <code>long</code> representing the floating point number,
 937:    * then writing this <code>long</code> value to the stream exactly the same
 938:    * as the <code>writeLong()</code> method does.
 939:    *
 940:    * @param val The double precision floating point number to write to the 
 941:    * stream.
 942:    *
 943:    * @exception IOException If an error occurs
 944:    *
 945:    * @see #writeLong(long)
 946:    */
 947:   public final void writeDouble (double val) throws IOException
 948:   {
 949:     if (out == null)
 950:       throw new IOException("Bad file descriptor");
 951: 
 952:     out.writeDouble(val);
 953:   }
 954: 
 955:   /**
 956:    * This method writes all the bytes in a <code>String</code> out to the
 957:    * stream.  One byte is written for each character in the <code>String</code>.
 958:    * The high eight bits of each character are discarded.
 959:    *
 960:    * @param val The <code>String</code> to write to the stream
 961:    *
 962:    * @exception IOException If an error occurs
 963:    */
 964:   public final void writeBytes (String val) throws IOException
 965:   {
 966:     if (out == null)
 967:       throw new IOException("Bad file descriptor");
 968: 
 969:     out.writeBytes(val);
 970:   }
 971:   
 972:   /**
 973:    * This method writes all the characters in a <code>String</code> to the
 974:    * stream.  There will be two bytes for each character value.  The high
 975:    * byte of the character will be written first.
 976:    *
 977:    * @param val The <code>String</code> to write to the stream.
 978:    *
 979:    * @exception IOException If an error occurs
 980:    */
 981:   public final void writeChars (String val) throws IOException
 982:   {
 983:     if (out == null)
 984:       throw new IOException("Bad file descriptor");
 985: 
 986:     out.writeChars(val);
 987:   }
 988:   
 989:   /**
 990:    * This method writes a Java <code>String</code> to the stream in a modified
 991:    * UTF-8 format.  First, two bytes are written to the stream indicating the
 992:    * number of bytes to follow.  Note that this is the number of bytes in the
 993:    * encoded <code>String</code> not the <code>String</code> length.  Next
 994:    * come the encoded characters.  Each character in the <code>String</code>
 995:    * is encoded as either one, two or three bytes.  For characters in the
 996:    * range of <code>&#92;u0001</code> to <code>&#92;u007F</code>, 
 997:    * one byte is used.  The character
 998:    * value goes into bits 0-7 and bit eight is 0.  For characters in the range
 999:    * of <code>&#92;u0080</code> to <code>&#92;u007FF</code>, two 
1000:    * bytes are used.  Bits
1001:    * 6-10 of the character value are encoded bits 0-4 of the first byte, with
1002:    * the high bytes having a value of "110".  Bits 0-5 of the character value
1003:    * are stored in bits 0-5 of the second byte, with the high bits set to
1004:    * "10".  This type of encoding is also done for the null character
1005:    * <code>&#92;u0000</code>.  This eliminates any C style NUL character values
1006:    * in the output.  All remaining characters are stored as three bytes.
1007:    * Bits 12-15 of the character value are stored in bits 0-3 of the first
1008:    * byte.  The high bits of the first bytes are set to "1110".  Bits 6-11
1009:    * of the character value are stored in bits 0-5 of the second byte.  The
1010:    * high bits of the second byte are set to "10".  And bits 0-5 of the
1011:    * character value are stored in bits 0-5 of byte three, with the high bits
1012:    * of that byte set to "10".
1013:    *
1014:    * @param val The <code>String</code> to write to the output in UTF format
1015:    *
1016:    * @exception IOException If an error occurs
1017:    */
1018:   public final void writeUTF (String val) throws IOException
1019:   {
1020:     if (out == null)
1021:       throw new IOException("Bad file descriptor");
1022: 
1023:     out.writeUTF(val);
1024:   }
1025:   
1026:   /**
1027:    * This method creates a java.nio.channels.FileChannel.
1028:    * Nio does not allow one to create a file channel directly.
1029:    * A file channel must be created by first creating an instance of
1030:    * Input/Output/RandomAccessFile and invoking the getChannel() method on it.
1031:    */
1032:   public final synchronized FileChannel getChannel ()
1033:   {
1034:     return ch;
1035:   }
1036: }