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