Frames | No Frames |
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 & 0xFF) << 8) | (byte2 & 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 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + 471: * ((byte3 & 0xFF) << 8) + (byte4 & 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 & 0xFF) << 56) + (((long)byte2 & 0xFF) << 48) + 535: * (((long)byte3 & 0xFF) << 40) + (((long)byte4 & 0xFF) << 32) + 536: * (((long)byte5 & 0xFF) << 24) + (((long)byte6 & 0xFF) << 16) + 537: * (((long)byte7 & 0xFF) << 8) + ((long)byte9 & 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 & 0xFF) << 8) | (byte2 & 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 & 0xFF) << 8) + (byte2 & 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>\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>\u0001</code> to <code>\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>\u0080</code> to <code>\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>\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: }