src/share/classes/java/io/RandomAccessFile.java

Print this page
rev 6052 : [mq]: jdk.patch


  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.nio.channels.FileChannel;
  29 import sun.nio.ch.FileChannelImpl;

  30 
  31 
  32 /**
  33  * Instances of this class support both reading and writing to a
  34  * random access file. A random access file behaves like a large
  35  * array of bytes stored in the file system. There is a kind of cursor,
  36  * or index into the implied array, called the <em>file pointer</em>;
  37  * input operations read bytes starting at the file pointer and advance
  38  * the file pointer past the bytes read. If the random access file is
  39  * created in read/write mode, then output operations are also available;
  40  * output operations write bytes starting at the file pointer and advance
  41  * the file pointer past the bytes written. Output operations that write
  42  * past the current end of the implied array cause the array to be
  43  * extended. The file pointer can be read by the
  44  * {@code getFilePointer} method and set by the {@code seek}
  45  * method.
  46  * <p>
  47  * It is generally true of all the reading routines in this class that
  48  * if end-of-file is reached before the desired number of bytes has been
  49  * read, an {@code EOFException} (which is a kind of
  50  * {@code IOException}) is thrown. If any byte cannot be read for
  51  * any reason other than end-of-file, an {@code IOException} other
  52  * than {@code EOFException} is thrown. In particular, an
  53  * {@code IOException} may be thrown if the stream has been closed.
  54  *
  55  * @author  unascribed
  56  * @since   JDK1.0
  57  */
  58 
  59 public class RandomAccessFile implements DataOutput, DataInput, Closeable {
  60 
  61     private FileDescriptor fd;
  62     private FileChannel channel = null;
  63     private boolean rw;

  64 
  65     private Object closeLock = new Object();
  66     private volatile boolean closed = false;
  67 
  68     private static final int O_RDONLY = 1;
  69     private static final int O_RDWR =   2;
  70     private static final int O_SYNC =   4;
  71     private static final int O_DSYNC =  8;
  72 
  73     /**
  74      * Creates a random access file stream to read from, and optionally
  75      * to write to, a file with the specified name. A new
  76      * {@link FileDescriptor} object is created to represent the
  77      * connection to the file.
  78      *
  79      * <p> The <tt>mode</tt> argument specifies the access mode with which the
  80      * file is to be opened.  The permitted values and their meanings are as
  81      * specified for the <a
  82      * href="#mode"><tt>RandomAccessFile(File,String)</tt></a> constructor.
  83      *


 213                     imode = -1;
 214             }
 215         }
 216         if (imode < 0)
 217             throw new IllegalArgumentException("Illegal mode \"" + mode
 218                                                + "\" must be one of "
 219                                                + "\"r\", \"rw\", \"rws\","
 220                                                + " or \"rwd\"");
 221         SecurityManager security = System.getSecurityManager();
 222         if (security != null) {
 223             security.checkRead(name);
 224             if (rw) {
 225                 security.checkWrite(name);
 226             }
 227         }
 228         if (name == null) {
 229             throw new NullPointerException();
 230         }
 231         fd = new FileDescriptor();
 232         fd.attach(this);

 233         open(name, imode);
 234     }
 235 
 236     /**
 237      * Returns the opaque file descriptor object associated with this
 238      * stream. </p>
 239      *
 240      * @return     the file descriptor object associated with this stream.
 241      * @exception  IOException  if an I/O error occurs.
 242      * @see        java.io.FileDescriptor
 243      */
 244     public final FileDescriptor getFD() throws IOException {
 245         if (fd != null) {
 246             return fd;
 247         }
 248         throw new IOException();
 249     }
 250 
 251     /**
 252      * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
 253      * object associated with this file.
 254      *
 255      * <p> The {@link java.nio.channels.FileChannel#position()
 256      * position} of the returned channel will always be equal to
 257      * this object's file-pointer offset as returned by the {@link
 258      * #getFilePointer getFilePointer} method.  Changing this object's
 259      * file-pointer offset, whether explicitly or by reading or writing bytes,
 260      * will change the position of the channel, and vice versa.  Changing the
 261      * file's length via this object will change the length seen via the file
 262      * channel, and vice versa.
 263      *
 264      * @return  the file channel associated with this file
 265      *
 266      * @since 1.4
 267      * @spec JSR-51
 268      */
 269     public final FileChannel getChannel() {
 270         synchronized (this) {
 271             if (channel == null) {
 272                 channel = FileChannelImpl.open(fd, true, rw, this);
 273             }
 274             return channel;
 275         }
 276     }
 277 
 278     /**
 279      * Opens a file and returns the file descriptor.  The file is
 280      * opened in read-write mode if the O_RDWR bit in {@code mode}
 281      * is true, else the file is opened as read-only.
 282      * If the {@code name} refers to a directory, an IOException
 283      * is thrown.
 284      *
 285      * @param name the name of the file
 286      * @param mode the mode flags, a combination of the O_ constants
 287      *             defined above
 288      */
 289     private native void open(String name, int mode)
 290         throws FileNotFoundException;
 291 
 292     // 'Read' primitives
 293 
 294     /**
 295      * Reads a byte of data from this file. The byte is returned as an
 296      * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This
 297      * method blocks if no input is yet available.
 298      * <p>
 299      * Although {@code RandomAccessFile} is not a subclass of
 300      * {@code InputStream}, this method behaves in exactly the same
 301      * way as the {@link InputStream#read()} method of
 302      * {@code InputStream}.
 303      *
 304      * @return     the next byte of data, or {@code -1} if the end of the
 305      *             file has been reached.
 306      * @exception  IOException  if an I/O error occurs. Not thrown if
 307      *                          end-of-file has been reached.
 308      */
 309     public native int read() throws IOException;







 310 
 311     /**
 312      * Reads a sub array as a sequence of bytes.
 313      * @param b the buffer into which the data is read.
 314      * @param off the start offset of the data.
 315      * @param len the number of bytes to read.
 316      * @exception IOException If an I/O error has occurred.
 317      */
 318     private native int readBytes(byte b[], int off, int len) throws IOException;







 319 
 320     /**
 321      * Reads up to {@code len} bytes of data from this file into an
 322      * array of bytes. This method blocks until at least one byte of input
 323      * is available.
 324      * <p>
 325      * Although {@code RandomAccessFile} is not a subclass of
 326      * {@code InputStream}, this method behaves in exactly the
 327      * same way as the {@link InputStream#read(byte[], int, int)} method of
 328      * {@code InputStream}.
 329      *
 330      * @param      b     the buffer into which the data is read.
 331      * @param      off   the start offset in array {@code b}
 332      *                   at which the data is written.
 333      * @param      len   the maximum number of bytes read.
 334      * @return     the total number of bytes read into the buffer, or
 335      *             {@code -1} if there is no more data because the end of
 336      *             the file has been reached.
 337      * @exception  IOException If the first byte cannot be read for any reason
 338      * other than end of file, or if the random access file has been closed, or if


 437         len = length();
 438         newpos = pos + n;
 439         if (newpos > len) {
 440             newpos = len;
 441         }
 442         seek(newpos);
 443 
 444         /* return the actual number of bytes skipped */
 445         return (int) (newpos - pos);
 446     }
 447 
 448     // 'Write' primitives
 449 
 450     /**
 451      * Writes the specified byte to this file. The write starts at
 452      * the current file pointer.
 453      *
 454      * @param      b   the {@code byte} to be written.
 455      * @exception  IOException  if an I/O error occurs.
 456      */
 457     public native void write(int b) throws IOException;






 458 
 459     /**
 460      * Writes a sub array as a sequence of bytes.
 461      * @param b the data to be written
 462 
 463      * @param off the start offset in the data
 464      * @param len the number of bytes that are written
 465      * @exception IOException If an I/O error has occurred.
 466      */
 467     private native void writeBytes(byte b[], int off, int len) throws IOException;






 468 
 469     /**
 470      * Writes {@code b.length} bytes from the specified byte array
 471      * to this file, starting at the current file pointer.
 472      *
 473      * @param      b   the data.
 474      * @exception  IOException  if an I/O error occurs.
 475      */
 476     public void write(byte b[]) throws IOException {
 477         writeBytes(b, 0, b.length);
 478     }
 479 
 480     /**
 481      * Writes {@code len} bytes from the specified byte array
 482      * starting at offset {@code off} to this file.
 483      *
 484      * @param      b     the data.
 485      * @param      off   the start offset in the data.
 486      * @param      len   the number of bytes to write.
 487      * @exception  IOException  if an I/O error occurs.




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.nio.channels.FileChannel;
  29 import sun.nio.ch.FileChannelImpl;
  30 import sun.misc.IoTrace;
  31 
  32 
  33 /**
  34  * Instances of this class support both reading and writing to a
  35  * random access file. A random access file behaves like a large
  36  * array of bytes stored in the file system. There is a kind of cursor,
  37  * or index into the implied array, called the <em>file pointer</em>;
  38  * input operations read bytes starting at the file pointer and advance
  39  * the file pointer past the bytes read. If the random access file is
  40  * created in read/write mode, then output operations are also available;
  41  * output operations write bytes starting at the file pointer and advance
  42  * the file pointer past the bytes written. Output operations that write
  43  * past the current end of the implied array cause the array to be
  44  * extended. The file pointer can be read by the
  45  * {@code getFilePointer} method and set by the {@code seek}
  46  * method.
  47  * <p>
  48  * It is generally true of all the reading routines in this class that
  49  * if end-of-file is reached before the desired number of bytes has been
  50  * read, an {@code EOFException} (which is a kind of
  51  * {@code IOException}) is thrown. If any byte cannot be read for
  52  * any reason other than end-of-file, an {@code IOException} other
  53  * than {@code EOFException} is thrown. In particular, an
  54  * {@code IOException} may be thrown if the stream has been closed.
  55  *
  56  * @author  unascribed
  57  * @since   JDK1.0
  58  */
  59 
  60 public class RandomAccessFile implements DataOutput, DataInput, Closeable {
  61 
  62     private FileDescriptor fd;
  63     private FileChannel channel = null;
  64     private boolean rw;
  65     private final String path;
  66 
  67     private Object closeLock = new Object();
  68     private volatile boolean closed = false;
  69 
  70     private static final int O_RDONLY = 1;
  71     private static final int O_RDWR =   2;
  72     private static final int O_SYNC =   4;
  73     private static final int O_DSYNC =  8;
  74 
  75     /**
  76      * Creates a random access file stream to read from, and optionally
  77      * to write to, a file with the specified name. A new
  78      * {@link FileDescriptor} object is created to represent the
  79      * connection to the file.
  80      *
  81      * <p> The <tt>mode</tt> argument specifies the access mode with which the
  82      * file is to be opened.  The permitted values and their meanings are as
  83      * specified for the <a
  84      * href="#mode"><tt>RandomAccessFile(File,String)</tt></a> constructor.
  85      *


 215                     imode = -1;
 216             }
 217         }
 218         if (imode < 0)
 219             throw new IllegalArgumentException("Illegal mode \"" + mode
 220                                                + "\" must be one of "
 221                                                + "\"r\", \"rw\", \"rws\","
 222                                                + " or \"rwd\"");
 223         SecurityManager security = System.getSecurityManager();
 224         if (security != null) {
 225             security.checkRead(name);
 226             if (rw) {
 227                 security.checkWrite(name);
 228             }
 229         }
 230         if (name == null) {
 231             throw new NullPointerException();
 232         }
 233         fd = new FileDescriptor();
 234         fd.attach(this);
 235         this.path = name;
 236         open(name, imode);
 237     }
 238 
 239     /**
 240      * Returns the opaque file descriptor object associated with this
 241      * stream. </p>
 242      *
 243      * @return     the file descriptor object associated with this stream.
 244      * @exception  IOException  if an I/O error occurs.
 245      * @see        java.io.FileDescriptor
 246      */
 247     public final FileDescriptor getFD() throws IOException {
 248         if (fd != null) {
 249             return fd;
 250         }
 251         throw new IOException();
 252     }
 253 
 254     /**
 255      * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
 256      * object associated with this file.
 257      *
 258      * <p> The {@link java.nio.channels.FileChannel#position()
 259      * position} of the returned channel will always be equal to
 260      * this object's file-pointer offset as returned by the {@link
 261      * #getFilePointer getFilePointer} method.  Changing this object's
 262      * file-pointer offset, whether explicitly or by reading or writing bytes,
 263      * will change the position of the channel, and vice versa.  Changing the
 264      * file's length via this object will change the length seen via the file
 265      * channel, and vice versa.
 266      *
 267      * @return  the file channel associated with this file
 268      *
 269      * @since 1.4
 270      * @spec JSR-51
 271      */
 272     public final FileChannel getChannel() {
 273         synchronized (this) {
 274             if (channel == null) {
 275                 channel = FileChannelImpl.open(fd, path, true, rw, this);
 276             }
 277             return channel;
 278         }
 279     }
 280 
 281     /**
 282      * Opens a file and returns the file descriptor.  The file is
 283      * opened in read-write mode if the O_RDWR bit in {@code mode}
 284      * is true, else the file is opened as read-only.
 285      * If the {@code name} refers to a directory, an IOException
 286      * is thrown.
 287      *
 288      * @param name the name of the file
 289      * @param mode the mode flags, a combination of the O_ constants
 290      *             defined above
 291      */
 292     private native void open(String name, int mode)
 293         throws FileNotFoundException;
 294 
 295     // 'Read' primitives
 296 
 297     /**
 298      * Reads a byte of data from this file. The byte is returned as an
 299      * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This
 300      * method blocks if no input is yet available.
 301      * <p>
 302      * Although {@code RandomAccessFile} is not a subclass of
 303      * {@code InputStream}, this method behaves in exactly the same
 304      * way as the {@link InputStream#read()} method of
 305      * {@code InputStream}.
 306      *
 307      * @return     the next byte of data, or {@code -1} if the end of the
 308      *             file has been reached.
 309      * @exception  IOException  if an I/O error occurs. Not thrown if
 310      *                          end-of-file has been reached.
 311      */
 312     public int read() throws IOException {
 313         Object traceHandle = IoTrace.fileReadBegin(path);
 314         int v = read0();
 315         IoTrace.fileReadEnd(traceHandle, v == -1 ? -1 : 1);
 316         return v;
 317     }
 318 
 319     private native int read0() throws IOException;
 320 
 321     /**
 322      * Reads a sub array as a sequence of bytes.
 323      * @param b the buffer into which the data is read.
 324      * @param off the start offset of the data.
 325      * @param len the number of bytes to read.
 326      * @exception IOException If an I/O error has occurred.
 327      */
 328     private int readBytes(byte b[], int off, int len) throws IOException {
 329         Object traceHandle = IoTrace.fileReadBegin(path);
 330         int v = readBytes0(b, off, len);
 331         IoTrace.fileReadEnd(traceHandle, v);
 332         return v;
 333     }
 334 
 335     private native int readBytes0(byte b[], int off, int len) throws IOException;
 336 
 337     /**
 338      * Reads up to {@code len} bytes of data from this file into an
 339      * array of bytes. This method blocks until at least one byte of input
 340      * is available.
 341      * <p>
 342      * Although {@code RandomAccessFile} is not a subclass of
 343      * {@code InputStream}, this method behaves in exactly the
 344      * same way as the {@link InputStream#read(byte[], int, int)} method of
 345      * {@code InputStream}.
 346      *
 347      * @param      b     the buffer into which the data is read.
 348      * @param      off   the start offset in array {@code b}
 349      *                   at which the data is written.
 350      * @param      len   the maximum number of bytes read.
 351      * @return     the total number of bytes read into the buffer, or
 352      *             {@code -1} if there is no more data because the end of
 353      *             the file has been reached.
 354      * @exception  IOException If the first byte cannot be read for any reason
 355      * other than end of file, or if the random access file has been closed, or if


 454         len = length();
 455         newpos = pos + n;
 456         if (newpos > len) {
 457             newpos = len;
 458         }
 459         seek(newpos);
 460 
 461         /* return the actual number of bytes skipped */
 462         return (int) (newpos - pos);
 463     }
 464 
 465     // 'Write' primitives
 466 
 467     /**
 468      * Writes the specified byte to this file. The write starts at
 469      * the current file pointer.
 470      *
 471      * @param      b   the {@code byte} to be written.
 472      * @exception  IOException  if an I/O error occurs.
 473      */
 474     public void write(int b) throws IOException {
 475         Object traceHandle = IoTrace.fileWriteBegin(path);
 476         write0(b);
 477         IoTrace.fileWriteEnd(traceHandle, 1);
 478     }
 479 
 480     private native void write0(int b) throws IOException;
 481 
 482     /**
 483      * Writes a sub array as a sequence of bytes.
 484      * @param b the data to be written

 485      * @param off the start offset in the data
 486      * @param len the number of bytes that are written
 487      * @exception IOException If an I/O error has occurred.
 488      */
 489     private void writeBytes(byte b[], int off, int len) throws IOException {
 490         Object traceHandle = IoTrace.fileWriteBegin(path);
 491         writeBytes0(b, off, len);
 492         IoTrace.fileWriteEnd(traceHandle, len);
 493     }
 494 
 495     private native void writeBytes0(byte b[], int off, int len) throws IOException;
 496 
 497     /**
 498      * Writes {@code b.length} bytes from the specified byte array
 499      * to this file, starting at the current file pointer.
 500      *
 501      * @param      b   the data.
 502      * @exception  IOException  if an I/O error occurs.
 503      */
 504     public void write(byte b[]) throws IOException {
 505         writeBytes(b, 0, b.length);
 506     }
 507 
 508     /**
 509      * Writes {@code len} bytes from the specified byte array
 510      * starting at offset {@code off} to this file.
 511      *
 512      * @param      b     the data.
 513      * @param      off   the start offset in the data.
 514      * @param      len   the number of bytes to write.
 515      * @exception  IOException  if an I/O error occurs.