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