0001: /*
0002: * @(#)RandomAccessFile.java 1.75 06/10/10
0003: *
0004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: *
0026: */
0027:
0028: package java.io;
0029:
0030: /**
0031: * Instances of this class support both reading and writing to a
0032: * random access file. A random access file behaves like a large
0033: * array of bytes stored in the file system. There is a kind of cursor,
0034: * or index into the implied array, called the <em>file pointer</em>;
0035: * input operations read bytes starting at the file pointer and advance
0036: * the file pointer past the bytes read. If the random access file is
0037: * created in read/write mode, then output operations are also available;
0038: * output operations write bytes starting at the file pointer and advance
0039: * the file pointer past the bytes written. Output operations that write
0040: * past the current end of the implied array cause the array to be
0041: * extended. The file pointer can be read by the
0042: * <code>getFilePointer</code> method and set by the <code>seek</code>
0043: * method.
0044: * <p>
0045: * It is generally true of all the reading routines in this class that
0046: * if end-of-file is reached before the desired number of bytes has been
0047: * read, an <code>EOFException</code> (which is a kind of
0048: * <code>IOException</code>) is thrown. If any byte cannot be read for
0049: * any reason other than end-of-file, an <code>IOException</code> other
0050: * than <code>EOFException</code> is thrown. In particular, an
0051: * <code>IOException</code> may be thrown if the stream has been closed.
0052: *
0053: * @author unascribed
0054: * @version 1.57, 05/03/00
0055: * @since JDK1.0
0056: */
0057:
0058: public class RandomAccessFile implements DataOutput, DataInput {
0059:
0060: private FileDescriptor fd;
0061: private boolean rw;
0062:
0063: private static final int O_RDONLY = 1;
0064: private static final int O_RDWR = 2;
0065: private static final int O_SYNC = 4;
0066: private static final int O_DSYNC = 8;
0067:
0068: /**
0069: * Creates a random access file stream to read from, and optionally
0070: * to write to, a file with the specified name. A new
0071: * {@link FileDescriptor} object is created to represent the
0072: * connection to the file.
0073: *
0074: * <p> The <tt>mode</tt> argument specifies the access mode with which the
0075: * file is to be opened. The permitted values and their meanings are as
0076: * specified for the <a
0077: * href="#mode"><tt>RandomAccessFile(File,String)</tt></a> constructor.
0078: *
0079: * <p>
0080: * If there is a security manager, its <code>checkRead</code> method
0081: * is called with the <code>name</code> argument
0082: * as its argument to see if read access to the file is allowed.
0083: * If the mode allows writing, the security manager's
0084: * <code>checkWrite</code> method
0085: * is also called with the <code>name</code> argument
0086: * as its argument to see if write access to the file is allowed.
0087: *
0088: * @param name the system-dependent filename
0089: * @param mode the access <a href="#mode">mode</a>
0090: * @exception IllegalArgumentException if the mode argument is not equal
0091: * to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
0092: * <tt>"rwd"</tt>
0093: * @exception FileNotFoundException if the file exists but is a directory
0094: * rather than a regular file, or cannot be opened or
0095: * created for any other reason
0096: * @exception SecurityException if a security manager exists and its
0097: * <code>checkRead</code> method denies read access to the file
0098: * or the mode is "rw" and the security manager's
0099: * <code>checkWrite</code> method denies write access to the file
0100: * @see java.lang.SecurityException
0101: * @see java.lang.SecurityManager#checkRead(java.lang.String)
0102: * @see java.lang.SecurityManager#checkWrite(java.lang.String)
0103: * @revised 1.4
0104: * @spec JSR-51
0105: */
0106: public RandomAccessFile(String name, String mode)
0107: throws FileNotFoundException {
0108: this (name != null ? new File(name) : null, mode);
0109: }
0110:
0111: /**
0112: * Creates a random access file stream to read from, and optionally to
0113: * write to, the file specified by the {@link File} argument. A new {@link
0114: * FileDescriptor} object is created to represent this file connection.
0115: *
0116: * <a name="mode"><p> The <tt>mode</tt> argument specifies the access mode
0117: * in which the file is to be opened. The permitted values and their
0118: * meanings are:
0119: *
0120: * <blockquote><table summary="Access mode permitted values and meanings">
0121: * <tr><th><p align="left">Value</p></th><th><p align="left">Meaning</p></th></tr>
0122: * <tr><td valign="top"><tt>"r"</tt></td>
0123: * <td> Open for reading only. Invoking any of the <tt>write</tt>
0124: * methods of the resulting object will cause an {@link
0125: * java.io.IOException} to be thrown. </td></tr>
0126: * <tr><td valign="top"><tt>"rw"</tt></td>
0127: * <td> Open for reading and writing. If the file does not already
0128: * exist then an attempt will be made to create it. </td></tr>
0129: * <tr><td valign="top"><tt>"rws"</tt></td>
0130: * <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
0131: * require that every update to the file's content or metadata be
0132: * written synchronously to the underlying storage device. </td></tr>
0133: * <tr><td valign="top"><tt>"rwd" </tt></td>
0134: * <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
0135: * require that every update to the file's content be written
0136: * synchronously to the underlying storage device. </td></tr>
0137: * </table></blockquote>
0138: *
0139: * If
0140: * the file resides on a local storage device then when an invocation of a
0141: * method of this class returns it is guaranteed that all changes made to
0142: * the file by that invocation will have been written to that device. This
0143: * is useful for ensuring that critical information is not lost in the
0144: * event of a system crash. If the file does not reside on a local device
0145: * then no such guarantee is made.
0146: *
0147: * <p> The <tt>"rwd"</tt> mode can be used to reduce the number of I/O
0148: * operations performed. Using <tt>"rwd"</tt> only requires updates to the
0149: * file's content to be written to storage; using <tt>"rws"</tt> requires
0150: * updates to both the file's content and its metadata to be written, which
0151: * generally requires at least one more low-level I/O operation.
0152: *
0153: * <p> If there is a security manager, its <code>checkRead</code> method is
0154: * called with the pathname of the <code>file</code> argument as its
0155: * argument to see if read access to the file is allowed. If the mode
0156: * allows writing, the security manager's <code>checkWrite</code> method is
0157: * also called with the path argument to see if write access to the file is
0158: * allowed.
0159: *
0160: * @param file the file object
0161: * @param mode the access mode, as described
0162: * <a href="#mode">above</a>
0163: * @exception IllegalArgumentException if the mode argument is not equal
0164: * to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
0165: * <tt>"rwd"</tt>
0166: * @exception FileNotFoundException if the file exists but is a directory
0167: * rather than a regular file, or cannot be opened or
0168: * created for any other reason
0169: * @exception SecurityException if a security manager exists and its
0170: * <code>checkRead</code> method denies read access to the file
0171: * or the mode is "rw" and the security manager's
0172: * <code>checkWrite</code> method denies write access to the file
0173: * @see java.lang.SecurityManager#checkRead(java.lang.String)
0174: * @see java.lang.SecurityManager#checkWrite(java.lang.String)
0175: * @revised 1.4
0176: * @spec JSR-51
0177: */
0178: public RandomAccessFile(File file, String mode)
0179: throws FileNotFoundException {
0180: String name = (file != null ? file.getPath() : null);
0181: int imode = -1;
0182: if (mode.equals("r"))
0183: imode = O_RDONLY;
0184: else if (mode.startsWith("rw")) {
0185: imode = O_RDWR;
0186: rw = true;
0187: if (mode.length() > 2) {
0188: if (mode.equals("rws"))
0189: imode |= O_SYNC;
0190: else if (mode.equals("rwd"))
0191: imode |= O_DSYNC;
0192: else
0193: imode = -1;
0194: }
0195: }
0196: if (imode < 0)
0197: throw new IllegalArgumentException("Illegal mode \"" + mode
0198: + "\" must be one of " + "\"r\", \"rw\", \"rws\","
0199: + " or \"rwd\"");
0200: SecurityManager security = System.getSecurityManager();
0201: if (security != null) {
0202: security.checkRead(name);
0203: if (rw) {
0204: security.checkWrite(name);
0205: }
0206: }
0207: if (name == null) {
0208: throw new NullPointerException();
0209: }
0210: fd = new FileDescriptor();
0211: open(name, imode);
0212: }
0213:
0214: /**
0215: * Returns the opaque file descriptor object associated with this
0216: * stream. </p>
0217: *
0218: * @return the file descriptor object associated with this stream.
0219: * @exception IOException if an I/O error occurs.
0220: * @see java.io.FileDescriptor
0221: */
0222: public final FileDescriptor getFD() throws IOException {
0223: if (fd != null)
0224: return fd;
0225: throw new IOException();
0226: }
0227:
0228: /**
0229: * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
0230: * object associated with this file.
0231: *
0232: * <p> The {@link java.nio.channels.FileChannel#position()
0233: * </code>position<code>} of the returned channel will always be equal to
0234: * this object's file-pointer offset as returned by the {@link
0235: * #getFilePointer getFilePointer} method. Changing this object's
0236: * file-pointer offset, whether explicitly or by reading or writing bytes,
0237: * will change the position of the channel, and vice versa. Changing the
0238: * file's length via this object will change the length seen via the file
0239: * channel, and vice versa.
0240: *
0241: * @return the file channel associated with this file
0242: *
0243: * @since 1.4
0244: * @spec JSR-51
0245: */
0246: /* NOTE: No NIO in CDC
0247: public final FileChannel getChannel() {
0248: synchronized (this) {
0249: if (channel == null)
0250: channel = FileChannelImpl.open(fd, true, rw, this);
0251: return channel;
0252: }
0253: }
0254: */
0255:
0256: /**
0257: * Opens a file and returns the file descriptor. The file is
0258: * opened in read-write mode if writeable is true, else
0259: * the file is opened as read-only.
0260: * If the <code>name</code> refers to a directory, an IOException
0261: * is thrown.
0262: *
0263: * @param name the name of the file
0264: * @param mode the mode flags, a combination of the O_ constants
0265: * defined above
0266: */
0267: private native void open(String name, int mode)
0268: throws FileNotFoundException;
0269:
0270: // 'Read' primitives
0271:
0272: /**
0273: * Reads a byte of data from this file. The byte is returned as an
0274: * integer in the range 0 to 255 (<code>0x00-0x0ff</code>). This
0275: * method blocks if no input is yet available.
0276: * <p>
0277: * Although <code>RandomAccessFile</code> is not a subclass of
0278: * <code>InputStream</code>, this method behaves in exactly the same
0279: * way as the {@link InputStream#read()} method of
0280: * <code>InputStream</code>.
0281: *
0282: * @return the next byte of data, or <code>-1</code> if the end of the
0283: * file has been reached.
0284: * @exception IOException if an I/O error occurs. Not thrown if
0285: * end-of-file has been reached.
0286: */
0287: public native int read() throws IOException;
0288:
0289: /**
0290: * Reads a sub array as a sequence of bytes.
0291: * @param b the data to be written
0292: * @param off the start offset in the data
0293: * @param len the number of bytes that are written
0294: * @exception IOException If an I/O error has occurred.
0295: */
0296: private native int readBytes(byte b[], int off, int len)
0297: throws IOException;
0298:
0299: /**
0300: * Reads up to <code>len</code> bytes of data from this file into an
0301: * array of bytes. This method blocks until at least one byte of input
0302: * is available.
0303: * <p>
0304: * Although <code>RandomAccessFile</code> is not a subclass of
0305: * <code>InputStream</code>, this method behaves in the exactly the
0306: * same way as the {@link InputStream#read(byte[], int, int)} method of
0307: * <code>InputStream</code>.
0308: *
0309: * @param b the buffer into which the data is read.
0310: * @param off the start offset of the data.
0311: * @param len the maximum number of bytes read.
0312: * @return the total number of bytes read into the buffer, or
0313: * <code>-1</code> if there is no more data because the end of
0314: * the file has been reached.
0315: * @exception IOException if an I/O error occurs.
0316: */
0317: public int read(byte b[], int off, int len) throws IOException {
0318: return readBytes(b, off, len);
0319: }
0320:
0321: /**
0322: * Reads up to <code>b.length</code> bytes of data from this file
0323: * into an array of bytes. This method blocks until at least one byte
0324: * of input is available.
0325: * <p>
0326: * Although <code>RandomAccessFile</code> is not a subclass of
0327: * <code>InputStream</code>, this method behaves in the exactly the
0328: * same way as the {@link InputStream#read(byte[])} method of
0329: * <code>InputStream</code>.
0330: *
0331: * @param b the buffer into which the data is read.
0332: * @return the total number of bytes read into the buffer, or
0333: * <code>-1</code> if there is no more data because the end of
0334: * this file has been reached.
0335: * @exception IOException if an I/O error occurs.
0336: */
0337: public int read(byte b[]) throws IOException {
0338: return readBytes(b, 0, b.length);
0339: }
0340:
0341: /**
0342: * Reads <code>b.length</code> bytes from this file into the byte
0343: * array, starting at the current file pointer. This method reads
0344: * repeatedly from the file until the requested number of bytes are
0345: * read. This method blocks until the requested number of bytes are
0346: * read, the end of the stream is detected, or an exception is thrown.
0347: *
0348: * @param b the buffer into which the data is read.
0349: * @exception EOFException if this file reaches the end before reading
0350: * all the bytes.
0351: * @exception IOException if an I/O error occurs.
0352: */
0353: public final void readFully(byte b[]) throws IOException {
0354: readFully(b, 0, b.length);
0355: }
0356:
0357: /**
0358: * Reads exactly <code>len</code> bytes from this file into the byte
0359: * array, starting at the current file pointer. This method reads
0360: * repeatedly from the file until the requested number of bytes are
0361: * read. This method blocks until the requested number of bytes are
0362: * read, the end of the stream is detected, or an exception is thrown.
0363: *
0364: * @param b the buffer into which the data is read.
0365: * @param off the start offset of the data.
0366: * @param len the number of bytes to read.
0367: * @exception EOFException if this file reaches the end before reading
0368: * all the bytes.
0369: * @exception IOException if an I/O error occurs.
0370: */
0371: public final void readFully(byte b[], int off, int len)
0372: throws IOException {
0373: int n = 0;
0374: do {
0375: int count = this .read(b, off + n, len - n);
0376: if (count < 0)
0377: throw new EOFException();
0378: n += count;
0379: } while (n < len);
0380: }
0381:
0382: /**
0383: * Attempts to skip over <code>n</code> bytes of input discarding the
0384: * skipped bytes.
0385: * <p>
0386: *
0387: * This method may skip over some smaller number of bytes, possibly zero.
0388: * This may result from any of a number of conditions; reaching end of
0389: * file before <code>n</code> bytes have been skipped is only one
0390: * possibility. This method never throws an <code>EOFException</code>.
0391: * The actual number of bytes skipped is returned. If <code>n</code>
0392: * is negative, no bytes are skipped.
0393: *
0394: * @param n the number of bytes to be skipped.
0395: * @return the actual number of bytes skipped.
0396: * @exception IOException if an I/O error occurs.
0397: */
0398: public int skipBytes(int n) throws IOException {
0399: long pos;
0400: long len;
0401: long newpos;
0402:
0403: if (n <= 0) {
0404: return 0;
0405: }
0406: pos = getFilePointer();
0407: len = length();
0408: newpos = pos + n;
0409: if (newpos > len) {
0410: newpos = len;
0411: }
0412: seek(newpos);
0413:
0414: /* return the actual number of bytes skipped */
0415: return (int) (newpos - pos);
0416: }
0417:
0418: // 'Write' primitives
0419:
0420: /**
0421: * Writes the specified byte to this file. The write starts at
0422: * the current file pointer.
0423: *
0424: * @param b the <code>byte</code> to be written.
0425: * @exception IOException if an I/O error occurs.
0426: */
0427: public native void write(int b) throws IOException;
0428:
0429: /**
0430: * Writes a sub array as a sequence of bytes.
0431: * @param b the data to be written
0432:
0433: * @param off the start offset in the data
0434: * @param len the number of bytes that are written
0435: * @exception IOException If an I/O error has occurred.
0436: */
0437: private native void writeBytes(byte b[], int off, int len)
0438: throws IOException;
0439:
0440: /**
0441: * Writes <code>b.length</code> bytes from the specified byte array
0442: * to this file, starting at the current file pointer.
0443: *
0444: * @param b the data.
0445: * @exception IOException if an I/O error occurs.
0446: */
0447: public void write(byte b[]) throws IOException {
0448: writeBytes(b, 0, b.length);
0449: }
0450:
0451: /**
0452: * Writes <code>len</code> bytes from the specified byte array
0453: * starting at offset <code>off</code> to this file.
0454: *
0455: * @param b the data.
0456: * @param off the start offset in the data.
0457: * @param len the number of bytes to write.
0458: * @exception IOException if an I/O error occurs.
0459: */
0460: public void write(byte b[], int off, int len) throws IOException {
0461: writeBytes(b, off, len);
0462: }
0463:
0464: // 'Random access' stuff
0465:
0466: /**
0467: * Returns the current offset in this file.
0468: *
0469: * @return the offset from the beginning of the file, in bytes,
0470: * at which the next read or write occurs.
0471: * @exception IOException if an I/O error occurs.
0472: */
0473: public native long getFilePointer() throws IOException;
0474:
0475: /**
0476: * Sets the file-pointer offset, measured from the beginning of this
0477: * file, at which the next read or write occurs. The offset may be
0478: * set beyond the end of the file. Setting the offset beyond the end
0479: * of the file does not change the file length. The file length will
0480: * change only by writing after the offset has been set beyond the end
0481: * of the file.
0482: *
0483: * @param pos the offset position, measured in bytes from the
0484: * beginning of the file, at which to set the file
0485: * pointer.
0486: * @exception IOException if <code>pos</code> is less than
0487: * <code>0</code> or if an I/O error occurs.
0488: */
0489: public native void seek(long pos) throws IOException;
0490:
0491: /**
0492: * Returns the length of this file.
0493: *
0494: * @return the length of this file, measured in bytes.
0495: * @exception IOException if an I/O error occurs.
0496: */
0497: public native long length() throws IOException;
0498:
0499: /**
0500: * Sets the length of this file.
0501: *
0502: * <p> If the present length of the file as returned by the
0503: * <code>length</code> method is greater than the <code>newLength</code>
0504: * argument then the file will be truncated. In this case, if the file
0505: * offset as returned by the <code>getFilePointer</code> method is greater
0506: * then <code>newLength</code> then after this method returns the offset
0507: * will be equal to <code>newLength</code>.
0508: *
0509: * <p> If the present length of the file as returned by the
0510: * <code>length</code> method is smaller than the <code>newLength</code>
0511: * argument then the file will be extended. In this case, the contents of
0512: * the extended portion of the file are not defined.
0513: *
0514: * @param newLength The desired length of the file
0515: * @exception IOException If an I/O error occurs
0516: * @since 1.2
0517: */
0518: public native void setLength(long newLength) throws IOException;
0519:
0520: /**
0521: * Closes this random access file stream and releases any system
0522: * resources associated with the stream. A closed random access
0523: * file cannot perform input or output operations and cannot be
0524: * reopened.
0525: *
0526: * @exception IOException if an I/O error occurs.
0527: *
0528: * @revised 1.4
0529: * @spec JSR-51
0530: */
0531: public void close() throws IOException {
0532: close0();
0533: }
0534:
0535: //
0536: // Some "reading/writing Java data types" methods stolen from
0537: // DataInputStream and DataOutputStream.
0538: //
0539:
0540: /**
0541: * Reads a <code>boolean</code> from this file. This method reads a
0542: * single byte from the file, starting at the current file pointer.
0543: * A value of <code>0</code> represents
0544: * <code>false</code>. Any other value represents <code>true</code>.
0545: * This method blocks until the byte is read, the end of the stream
0546: * is detected, or an exception is thrown.
0547: *
0548: * @return the <code>boolean</code> value read.
0549: * @exception EOFException if this file has reached the end.
0550: * @exception IOException if an I/O error occurs.
0551: */
0552: public final boolean readBoolean() throws IOException {
0553: int ch = this .read();
0554: if (ch < 0)
0555: throw new EOFException();
0556: return (ch != 0);
0557: }
0558:
0559: /**
0560: * Reads a signed eight-bit value from this file. This method reads a
0561: * byte from the file, starting from the current file pointer.
0562: * If the byte read is <code>b</code>, where
0563: * <code>0 <= b <= 255</code>,
0564: * then the result is:
0565: * <blockquote><pre>
0566: * (byte)(b)
0567: * </pre></blockquote>
0568: * <p>
0569: * This method blocks until the byte is read, the end of the stream
0570: * is detected, or an exception is thrown.
0571: *
0572: * @return the next byte of this file as a signed eight-bit
0573: * <code>byte</code>.
0574: * @exception EOFException if this file has reached the end.
0575: * @exception IOException if an I/O error occurs.
0576: */
0577: public final byte readByte() throws IOException {
0578: int ch = this .read();
0579: if (ch < 0)
0580: throw new EOFException();
0581: return (byte) (ch);
0582: }
0583:
0584: /**
0585: * Reads an unsigned eight-bit number from this file. This method reads
0586: * a byte from this file, starting at the current file pointer,
0587: * and returns that byte.
0588: * <p>
0589: * This method blocks until the byte is read, the end of the stream
0590: * is detected, or an exception is thrown.
0591: *
0592: * @return the next byte of this file, interpreted as an unsigned
0593: * eight-bit number.
0594: * @exception EOFException if this file has reached the end.
0595: * @exception IOException if an I/O error occurs.
0596: */
0597: public final int readUnsignedByte() throws IOException {
0598: int ch = this .read();
0599: if (ch < 0)
0600: throw new EOFException();
0601: return ch;
0602: }
0603:
0604: /**
0605: * Reads a signed 16-bit number from this file. The method reads two
0606: * bytes from this file, starting at the current file pointer.
0607: * If the two bytes read, in order, are
0608: * <code>b1</code> and <code>b2</code>, where each of the two values is
0609: * between <code>0</code> and <code>255</code>, inclusive, then the
0610: * result is equal to:
0611: * <blockquote><pre>
0612: * (short)((b1 << 8) | b2)
0613: * </pre></blockquote>
0614: * <p>
0615: * This method blocks until the two bytes are read, the end of the
0616: * stream is detected, or an exception is thrown.
0617: *
0618: * @return the next two bytes of this file, interpreted as a signed
0619: * 16-bit number.
0620: * @exception EOFException if this file reaches the end before reading
0621: * two bytes.
0622: * @exception IOException if an I/O error occurs.
0623: */
0624: public final short readShort() throws IOException {
0625: int ch1 = this .read();
0626: int ch2 = this .read();
0627: if ((ch1 | ch2) < 0)
0628: throw new EOFException();
0629: return (short) ((ch1 << 8) + (ch2 << 0));
0630: }
0631:
0632: /**
0633: * Reads an unsigned 16-bit number from this file. This method reads
0634: * two bytes from the file, starting at the current file pointer.
0635: * If the bytes read, in order, are
0636: * <code>b1</code> and <code>b2</code>, where
0637: * <code>0 <= b1, b2 <= 255</code>,
0638: * then the result is equal to:
0639: * <blockquote><pre>
0640: * (b1 << 8) | b2
0641: * </pre></blockquote>
0642: * <p>
0643: * This method blocks until the two bytes are read, the end of the
0644: * stream is detected, or an exception is thrown.
0645: *
0646: * @return the next two bytes of this file, interpreted as an unsigned
0647: * 16-bit integer.
0648: * @exception EOFException if this file reaches the end before reading
0649: * two bytes.
0650: * @exception IOException if an I/O error occurs.
0651: */
0652: public final int readUnsignedShort() throws IOException {
0653: int ch1 = this .read();
0654: int ch2 = this .read();
0655: if ((ch1 | ch2) < 0)
0656: throw new EOFException();
0657: return (ch1 << 8) + (ch2 << 0);
0658: }
0659:
0660: /**
0661: * Reads a Unicode character from this file. This method reads two
0662: * bytes from the file, starting at the current file pointer.
0663: * If the bytes read, in order, are
0664: * <code>b1</code> and <code>b2</code>, where
0665: * <code>0 <= b1, b2 <= 255</code>,
0666: * then the result is equal to:
0667: * <blockquote><pre>
0668: * (char)((b1 << 8) | b2)
0669: * </pre></blockquote>
0670: * <p>
0671: * This method blocks until the two bytes are read, the end of the
0672: * stream is detected, or an exception is thrown.
0673: *
0674: * @return the next two bytes of this file as a Unicode character.
0675: * @exception EOFException if this file reaches the end before reading
0676: * two bytes.
0677: * @exception IOException if an I/O error occurs.
0678: */
0679: public final char readChar() throws IOException {
0680: int ch1 = this .read();
0681: int ch2 = this .read();
0682: if ((ch1 | ch2) < 0)
0683: throw new EOFException();
0684: return (char) ((ch1 << 8) + (ch2 << 0));
0685: }
0686:
0687: /**
0688: * Reads a signed 32-bit integer from this file. This method reads 4
0689: * bytes from the file, starting at the current file pointer.
0690: * If the bytes read, in order, are <code>b1</code>,
0691: * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
0692: * <code>0 <= b1, b2, b3, b4 <= 255</code>,
0693: * then the result is equal to:
0694: * <blockquote><pre>
0695: * (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
0696: * </pre></blockquote>
0697: * <p>
0698: * This method blocks until the four bytes are read, the end of the
0699: * stream is detected, or an exception is thrown.
0700: *
0701: * @return the next four bytes of this file, interpreted as an
0702: * <code>int</code>.
0703: * @exception EOFException if this file reaches the end before reading
0704: * four bytes.
0705: * @exception IOException if an I/O error occurs.
0706: */
0707: public final int readInt() throws IOException {
0708: int ch1 = this .read();
0709: int ch2 = this .read();
0710: int ch3 = this .read();
0711: int ch4 = this .read();
0712: if ((ch1 | ch2 | ch3 | ch4) < 0)
0713: throw new EOFException();
0714: return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
0715: }
0716:
0717: /**
0718: * Reads a signed 64-bit integer from this file. This method reads eight
0719: * bytes from the file, starting at the current file pointer.
0720: * If the bytes read, in order, are
0721: * <code>b1</code>, <code>b2</code>, <code>b3</code>,
0722: * <code>b4</code>, <code>b5</code>, <code>b6</code>,
0723: * <code>b7</code>, and <code>b8,</code> where:
0724: * <blockquote><pre>
0725: * 0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
0726: * </pre></blockquote>
0727: * <p>
0728: * then the result is equal to:
0729: * <p><blockquote><pre>
0730: * ((long)b1 << 56) + ((long)b2 << 48)
0731: * + ((long)b3 << 40) + ((long)b4 << 32)
0732: * + ((long)b5 << 24) + ((long)b6 << 16)
0733: * + ((long)b7 << 8) + b8
0734: * </pre></blockquote>
0735: * <p>
0736: * This method blocks until the eight bytes are read, the end of the
0737: * stream is detected, or an exception is thrown.
0738: *
0739: * @return the next eight bytes of this file, interpreted as a
0740: * <code>long</code>.
0741: * @exception EOFException if this file reaches the end before reading
0742: * eight bytes.
0743: * @exception IOException if an I/O error occurs.
0744: */
0745: public final long readLong() throws IOException {
0746: return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
0747: }
0748:
0749: /**
0750: * Reads a <code>float</code> from this file. This method reads an
0751: * <code>int</code> value, starting at the current file pointer,
0752: * as if by the <code>readInt</code> method
0753: * and then converts that <code>int</code> to a <code>float</code>
0754: * using the <code>intBitsToFloat</code> method in class
0755: * <code>Float</code>.
0756: * <p>
0757: * This method blocks until the four bytes are read, the end of the
0758: * stream is detected, or an exception is thrown.
0759: *
0760: * @return the next four bytes of this file, interpreted as a
0761: * <code>float</code>.
0762: * @exception EOFException if this file reaches the end before reading
0763: * four bytes.
0764: * @exception IOException if an I/O error occurs.
0765: * @see java.io.RandomAccessFile#readInt()
0766: * @see java.lang.Float#intBitsToFloat(int)
0767: */
0768: public final float readFloat() throws IOException {
0769: return Float.intBitsToFloat(readInt());
0770: }
0771:
0772: /**
0773: * Reads a <code>double</code> from this file. This method reads a
0774: * <code>long</code> value, starting at the current file pointer,
0775: * as if by the <code>readLong</code> method
0776: * and then converts that <code>long</code> to a <code>double</code>
0777: * using the <code>longBitsToDouble</code> method in
0778: * class <code>Double</code>.
0779: * <p>
0780: * This method blocks until the eight bytes are read, the end of the
0781: * stream is detected, or an exception is thrown.
0782: *
0783: * @return the next eight bytes of this file, interpreted as a
0784: * <code>double</code>.
0785: * @exception EOFException if this file reaches the end before reading
0786: * eight bytes.
0787: * @exception IOException if an I/O error occurs.
0788: * @see java.io.RandomAccessFile#readLong()
0789: * @see java.lang.Double#longBitsToDouble(long)
0790: */
0791: public final double readDouble() throws IOException {
0792: return Double.longBitsToDouble(readLong());
0793: }
0794:
0795: /**
0796: * Reads the next line of text from this file. This method successively
0797: * reads bytes from the file, starting at the current file pointer,
0798: * until it reaches a line terminator or the end
0799: * of the file. Each byte is converted into a character by taking the
0800: * byte's value for the lower eight bits of the character and setting the
0801: * high eight bits of the character to zero. This method does not,
0802: * therefore, support the full Unicode character set.
0803: *
0804: * <p> A line of text is terminated by a carriage-return character
0805: * (<code>'\r'</code>), a newline character (<code>'\n'</code>), a
0806: * carriage-return character immediately followed by a newline character,
0807: * or the end of the file. Line-terminating characters are discarded and
0808: * are not included as part of the string returned.
0809: *
0810: * <p> This method blocks until a newline character is read, a carriage
0811: * return and the byte following it are read (to see if it is a newline),
0812: * the end of the file is reached, or an exception is thrown.
0813: *
0814: * @return the next line of text from this file, or null if end
0815: * of file is encountered before even one byte is read.
0816: * @exception IOException if an I/O error occurs.
0817: */
0818:
0819: public final String readLine() throws IOException {
0820: StringBuffer input = new StringBuffer();
0821: int c = -1;
0822: boolean eol = false;
0823:
0824: while (!eol) {
0825: switch (c = read()) {
0826: case -1:
0827: case '\n':
0828: eol = true;
0829: break;
0830: case '\r':
0831: eol = true;
0832: long cur = getFilePointer();
0833: if ((read()) != '\n') {
0834: seek(cur);
0835: }
0836: break;
0837: default:
0838: input.append((char) c);
0839: break;
0840: }
0841: }
0842:
0843: if ((c == -1) && (input.length() == 0)) {
0844: return null;
0845: }
0846: return input.toString();
0847: }
0848:
0849: /**
0850: * Reads in a string from this file. The string has been encoded
0851: * using a modified UTF-8 format.
0852: * <p>
0853: * The first two bytes are read, starting from the current file
0854: * pointer, as if by
0855: * <code>readUnsignedShort</code>. This value gives the number of
0856: * following bytes that are in the encoded string, not
0857: * the length of the resulting string. The following bytes are then
0858: * interpreted as bytes encoding characters in the UTF-8 format
0859: * and are converted into characters.
0860: * <p>
0861: * This method blocks until all the bytes are read, the end of the
0862: * stream is detected, or an exception is thrown.
0863: *
0864: * @return a Unicode string.
0865: * @exception EOFException if this file reaches the end before
0866: * reading all the bytes.
0867: * @exception IOException if an I/O error occurs.
0868: * @exception UTFDataFormatException if the bytes do not represent
0869: * valid UTF-8 encoding of a Unicode string.
0870: * @see java.io.RandomAccessFile#readUnsignedShort()
0871: */
0872: public final String readUTF() throws IOException {
0873: return DataInputStream.readUTF(this );
0874: }
0875:
0876: /**
0877: * Writes a <code>boolean</code> to the file as a one-byte value. The
0878: * value <code>true</code> is written out as the value
0879: * <code>(byte)1</code>; the value <code>false</code> is written out
0880: * as the value <code>(byte)0</code>. The write starts at
0881: * the current position of the file pointer.
0882: *
0883: * @param v a <code>boolean</code> value to be written.
0884: * @exception IOException if an I/O error occurs.
0885: */
0886: public final void writeBoolean(boolean v) throws IOException {
0887: write(v ? 1 : 0);
0888: //written++;
0889: }
0890:
0891: /**
0892: * Writes a <code>byte</code> to the file as a one-byte value. The
0893: * write starts at the current position of the file pointer.
0894: *
0895: * @param v a <code>byte</code> value to be written.
0896: * @exception IOException if an I/O error occurs.
0897: */
0898: public final void writeByte(int v) throws IOException {
0899: write(v);
0900: //written++;
0901: }
0902:
0903: /**
0904: * Writes a <code>short</code> to the file as two bytes, high byte first.
0905: * The write starts at the current position of the file pointer.
0906: *
0907: * @param v a <code>short</code> to be written.
0908: * @exception IOException if an I/O error occurs.
0909: */
0910: public final void writeShort(int v) throws IOException {
0911: write((v >>> 8) & 0xFF);
0912: write((v >>> 0) & 0xFF);
0913: //written += 2;
0914: }
0915:
0916: /**
0917: * Writes a <code>char</code> to the file as a two-byte value, high
0918: * byte first. The write starts at the current position of the
0919: * file pointer.
0920: *
0921: * @param v a <code>char</code> value to be written.
0922: * @exception IOException if an I/O error occurs.
0923: */
0924: public final void writeChar(int v) throws IOException {
0925: write((v >>> 8) & 0xFF);
0926: write((v >>> 0) & 0xFF);
0927: //written += 2;
0928: }
0929:
0930: /**
0931: * Writes an <code>int</code> to the file as four bytes, high byte first.
0932: * The write starts at the current position of the file pointer.
0933: *
0934: * @param v an <code>int</code> to be written.
0935: * @exception IOException if an I/O error occurs.
0936: */
0937: public final void writeInt(int v) throws IOException {
0938: write((v >>> 24) & 0xFF);
0939: write((v >>> 16) & 0xFF);
0940: write((v >>> 8) & 0xFF);
0941: write((v >>> 0) & 0xFF);
0942: //written += 4;
0943: }
0944:
0945: /**
0946: * Writes a <code>long</code> to the file as eight bytes, high byte first.
0947: * The write starts at the current position of the file pointer.
0948: *
0949: * @param v a <code>long</code> to be written.
0950: * @exception IOException if an I/O error occurs.
0951: */
0952: public final void writeLong(long v) throws IOException {
0953: write((int) (v >>> 56) & 0xFF);
0954: write((int) (v >>> 48) & 0xFF);
0955: write((int) (v >>> 40) & 0xFF);
0956: write((int) (v >>> 32) & 0xFF);
0957: write((int) (v >>> 24) & 0xFF);
0958: write((int) (v >>> 16) & 0xFF);
0959: write((int) (v >>> 8) & 0xFF);
0960: write((int) (v >>> 0) & 0xFF);
0961: //written += 8;
0962: }
0963:
0964: /**
0965: * Converts the float argument to an <code>int</code> using the
0966: * <code>floatToIntBits</code> method in class <code>Float</code>,
0967: * and then writes that <code>int</code> value to the file as a
0968: * four-byte quantity, high byte first. The write starts at the
0969: * current position of the file pointer.
0970: *
0971: * @param v a <code>float</code> value to be written.
0972: * @exception IOException if an I/O error occurs.
0973: * @see java.lang.Float#floatToIntBits(float)
0974: */
0975: public final void writeFloat(float v) throws IOException {
0976: writeInt(Float.floatToIntBits(v));
0977: }
0978:
0979: /**
0980: * Converts the double argument to a <code>long</code> using the
0981: * <code>doubleToLongBits</code> method in class <code>Double</code>,
0982: * and then writes that <code>long</code> value to the file as an
0983: * eight-byte quantity, high byte first. The write starts at the current
0984: * position of the file pointer.
0985: *
0986: * @param v a <code>double</code> value to be written.
0987: * @exception IOException if an I/O error occurs.
0988: * @see java.lang.Double#doubleToLongBits(double)
0989: */
0990: public final void writeDouble(double v) throws IOException {
0991: writeLong(Double.doubleToLongBits(v));
0992: }
0993:
0994: /**
0995: * Writes the string to the file as a sequence of bytes. Each
0996: * character in the string is written out, in sequence, by discarding
0997: * its high eight bits. The write starts at the current position of
0998: * the file pointer.
0999: *
1000: * @param s a string of bytes to be written.
1001: * @exception IOException if an I/O error occurs.
1002: */
1003: public final void writeBytes(String s) throws IOException {
1004: int len = s.length();
1005:
1006: char[] val = new char[len];
1007: s.getChars(0, len, val, 0);
1008:
1009: byte[] b = new byte[len];
1010:
1011: for (int i = 0; i < len; ++i) {
1012: b[i] = (byte) val[i];
1013: }
1014:
1015: writeBytes(b, 0, len);
1016:
1017: }
1018:
1019: /**
1020: * Writes a string to the file as a sequence of characters. Each
1021: * character is written to the data output stream as if by the
1022: * <code>writeChar</code> method. The write starts at the current
1023: * position of the file pointer.
1024: *
1025: * @param s a <code>String</code> value to be written.
1026: * @exception IOException if an I/O error occurs.
1027: * @see java.io.RandomAccessFile#writeChar(int)
1028: */
1029: public final void writeChars(String s) throws IOException {
1030: int clen = s.length();
1031: int blen = 2 * clen;
1032: byte[] b = new byte[blen];
1033: char[] c = new char[clen];
1034: s.getChars(0, clen, c, 0);
1035: for (int i = 0, j = 0; i < clen; i++) {
1036: b[j++] = (byte) (c[i] >>> 8);
1037: b[j++] = (byte) (c[i] >>> 0);
1038: }
1039: writeBytes(b, 0, blen);
1040: }
1041:
1042: /**
1043: * Writes a string to the file using UTF-8 encoding in a
1044: * machine-independent manner.
1045: * <p>
1046: * First, two bytes are written to the file, starting at the
1047: * current file pointer, as if by the
1048: * <code>writeShort</code> method giving the number of bytes to
1049: * follow. This value is the number of bytes actually written out,
1050: * not the length of the string. Following the length, each character
1051: * of the string is output, in sequence, using the UTF-8 encoding
1052: * for each character.
1053: *
1054: * @param str a string to be written.
1055: * @exception IOException if an I/O error occurs.
1056: */
1057: public final void writeUTF(String str) throws IOException {
1058: DataOutputStream.writeUTF(str, this );
1059: }
1060:
1061: private static native void initIDs();
1062:
1063: private native void close0() throws IOException;
1064:
1065: static {
1066: initIDs();
1067: }
1068:
1069: }
|