< prev index next >

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

Print this page

  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 
  30 import jdk.internal.access.JavaIORandomAccessFileAccess;
  31 import jdk.internal.access.SharedSecrets;

  32 import sun.nio.ch.FileChannelImpl;
  33 
  34 
  35 /**
  36  * Instances of this class support both reading and writing to a
  37  * random access file. A random access file behaves like a large
  38  * array of bytes stored in the file system. There is a kind of cursor,
  39  * or index into the implied array, called the <em>file pointer</em>;
  40  * input operations read bytes starting at the file pointer and advance
  41  * the file pointer past the bytes read. If the random access file is
  42  * created in read/write mode, then output operations are also available;
  43  * output operations write bytes starting at the file pointer and advance
  44  * the file pointer past the bytes written. Output operations that write
  45  * past the current end of the implied array cause the array to be
  46  * extended. The file pointer can be read by the
  47  * {@code getFilePointer} method and set by the {@code seek}
  48  * method.
  49  * <p>
  50  * It is generally true of all the reading routines in this class that
  51  * if end-of-file is reached before the desired number of bytes has been

 322      *
 323      * @param name the name of the file
 324      * @param mode the mode flags, a combination of the O_ constants
 325      *             defined above
 326      */
 327     private native void open0(String name, int mode)
 328         throws FileNotFoundException;
 329 
 330     // wrap native call to allow instrumentation
 331     /**
 332      * Opens a file and returns the file descriptor.  The file is
 333      * opened in read-write mode if the O_RDWR bit in {@code mode}
 334      * is true, else the file is opened as read-only.
 335      * If the {@code name} refers to a directory, an IOException
 336      * is thrown.
 337      *
 338      * @param name the name of the file
 339      * @param mode the mode flags, a combination of the O_ constants
 340      *             defined above
 341      */
 342     private void open(String name, int mode)
 343         throws FileNotFoundException {
 344         open0(name, mode);



 345     }
 346 
 347     // 'Read' primitives
 348 
 349     /**
 350      * Reads a byte of data from this file. The byte is returned as an
 351      * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This
 352      * method blocks if no input is yet available.
 353      * <p>
 354      * Although {@code RandomAccessFile} is not a subclass of
 355      * {@code InputStream}, this method behaves in exactly the same
 356      * way as the {@link InputStream#read()} method of
 357      * {@code InputStream}.
 358      *
 359      * @return     the next byte of data, or {@code -1} if the end of the
 360      *             file has been reached.
 361      * @throws     IOException  if an I/O error occurs. Not thrown if
 362      *                          end-of-file has been reached.
 363      */
 364     public int read() throws IOException {
 365         return read0();




 366     }
 367 
 368     private native int read0() throws IOException;
 369 
 370     /**
 371      * Reads a sub array as a sequence of bytes.
 372      * @param     b the buffer into which the data is read.
 373      * @param     off the start offset of the data.
 374      * @param     len the number of bytes to read.
 375      * @throws    IOException If an I/O error has occurred.
 376      */
 377     private native int readBytes(byte[] b, int off, int len) throws IOException;








 378 
 379     /**
 380      * Reads up to {@code len} bytes of data from this file into an
 381      * array of bytes. This method blocks until at least one byte of input
 382      * is available.
 383      * <p>
 384      * Although {@code RandomAccessFile} is not a subclass of
 385      * {@code InputStream}, this method behaves in exactly the
 386      * same way as the {@link InputStream#read(byte[], int, int)} method of
 387      * {@code InputStream}.
 388      *
 389      * @param      b     the buffer into which the data is read.
 390      * @param      off   the start offset in array {@code b}
 391      *                   at which the data is written.
 392      * @param      len   the maximum number of bytes read.
 393      * @return     the total number of bytes read into the buffer, or
 394      *             {@code -1} if there is no more data because the end of
 395      *             the file has been reached.
 396      * @throws     IOException If the first byte cannot be read for any reason
 397      *             other than end of file, or if the random access file has been closed,
 398      *             or if some other I/O error occurs.
 399      * @throws     NullPointerException If {@code b} is {@code null}.
 400      * @throws     IndexOutOfBoundsException If {@code off} is negative,
 401      *             {@code len} is negative, or {@code len} is greater than
 402      *             {@code b.length - off}
 403      */
 404     public int read(byte[] b, int off, int len) throws IOException {
 405         return readBytes(b, off, len);




 406     }
 407 
 408     /**
 409      * Reads up to {@code b.length} bytes of data from this file
 410      * into an array of bytes. This method blocks until at least one byte
 411      * of input is available.
 412      * <p>
 413      * Although {@code RandomAccessFile} is not a subclass of
 414      * {@code InputStream}, this method behaves in exactly the
 415      * same way as the {@link InputStream#read(byte[])} method of
 416      * {@code InputStream}.
 417      *
 418      * @param      b   the buffer into which the data is read.
 419      * @return     the total number of bytes read into the buffer, or
 420      *             {@code -1} if there is no more data because the end of
 421      *             this file has been reached.
 422      * @throws     IOException If the first byte cannot be read for any reason
 423      *             other than end of file, or if the random access file has been closed,
 424      *             or if some other I/O error occurs.
 425      * @throws     NullPointerException If {@code b} is {@code null}.
 426      */
 427     public int read(byte[] b) throws IOException {
 428         return readBytes(b, 0, b.length);
 429     }
 430 
 431     /**
 432      * Reads {@code b.length} bytes from this file into the byte
 433      * array, starting at the current file pointer. This method reads
 434      * repeatedly from the file until the requested number of bytes are
 435      * read. This method blocks until the requested number of bytes are
 436      * read, the end of the stream is detected, or an exception is thrown.
 437      *
 438      * @param   b   the buffer into which the data is read.
 439      * @throws  NullPointerException if {@code b} is {@code null}.
 440      * @throws  EOFException  if this file reaches the end before reading
 441      *              all the bytes.
 442      * @throws  IOException   if an I/O error occurs.
 443      */
 444     public final void readFully(byte[] b) throws IOException {
 445         readFully(b, 0, b.length);
 446     }
 447 
 448     /**

 502         newpos = pos + n;
 503         if (newpos > len) {
 504             newpos = len;
 505         }
 506         seek(newpos);
 507 
 508         /* return the actual number of bytes skipped */
 509         return (int) (newpos - pos);
 510     }
 511 
 512     // 'Write' primitives
 513 
 514     /**
 515      * Writes the specified byte to this file. The write starts at
 516      * the current file pointer.
 517      *
 518      * @param      b   the {@code byte} to be written.
 519      * @throws     IOException  if an I/O error occurs.
 520      */
 521     public void write(int b) throws IOException {
 522         write0(b);




 523     }
 524 
 525     private native void write0(int b) throws IOException;
 526 
 527     /**
 528      * Writes a sub array as a sequence of bytes.
 529      *
 530      * @param     b the data to be written
 531      * @param     off the start offset in the data
 532      * @param     len the number of bytes that are written
 533      * @throws    IOException If an I/O error has occurred.
 534      */
 535     private native void writeBytes(byte[] b, int off, int len) throws IOException;








 536 
 537     /**
 538      * Writes {@code b.length} bytes from the specified byte array
 539      * to this file, starting at the current file pointer.
 540      *
 541      * @param      b   the data.
 542      * @throws     IOException  if an I/O error occurs.
 543      */
 544     public void write(byte[] b) throws IOException {
 545         writeBytes(b, 0, b.length);
 546     }
 547 
 548     /**
 549      * Writes {@code len} bytes from the specified byte array
 550      * starting at offset {@code off} to this file.
 551      *
 552      * @param      b     the data.
 553      * @param      off   the start offset in the data.
 554      * @param      len   the number of bytes to write.
 555      * @throws     IOException  if an I/O error occurs.
 556      */
 557     public void write(byte[] b, int off, int len) throws IOException {
 558         writeBytes(b, off, len);
 559     }
 560 
 561     // 'Random access' stuff
 562 
 563     /**
 564      * Returns the current offset in this file.
 565      *

 569      */
 570     public native long getFilePointer() throws IOException;
 571 
 572     /**
 573      * Sets the file-pointer offset, measured from the beginning of this
 574      * file, at which the next read or write occurs.  The offset may be
 575      * set beyond the end of the file. Setting the offset beyond the end
 576      * of the file does not change the file length.  The file length will
 577      * change only by writing after the offset has been set beyond the end
 578      * of the file.
 579      *
 580      * @param      pos   the offset position, measured in bytes from the
 581      *                   beginning of the file, at which to set the file
 582      *                   pointer.
 583      * @throws     IOException  if {@code pos} is less than
 584      *                          {@code 0} or if an I/O error occurs.
 585      */
 586     public void seek(long pos) throws IOException {
 587         if (pos < 0) {
 588             throw new IOException("Negative seek offset");



 589         } else {
 590             seek0(pos);
 591         }
 592     }
 593 
 594     private native void seek0(long pos) throws IOException;
 595 
 596     /**
 597      * Returns the length of this file.
 598      *
 599      * @return     the length of this file, measured in bytes.
 600      * @throws     IOException  if an I/O error occurs.
 601      */
 602     public native long length() throws IOException;








 603 
 604     /**
 605      * Sets the length of this file.
 606      *
 607      * <p> If the present length of the file as returned by the
 608      * {@code length} method is greater than the {@code newLength}
 609      * argument then the file will be truncated.  In this case, if the file
 610      * offset as returned by the {@code getFilePointer} method is greater
 611      * than {@code newLength} then after this method returns the offset
 612      * will be equal to {@code newLength}.
 613      *
 614      * <p> If the present length of the file as returned by the
 615      * {@code length} method is smaller than the {@code newLength}
 616      * argument then the file will be extended.  In this case, the contents of
 617      * the extended portion of the file are not defined.
 618      *
 619      * @param      newLength    The desired length of the file
 620      * @throws     IOException  If an I/O error occurs
 621      * @since      1.2
 622      */
 623     public native void setLength(long newLength) throws IOException;








 624 
 625     /**
 626      * Closes this random access file stream and releases any system
 627      * resources associated with the stream. A closed random access
 628      * file cannot perform input or output operations and cannot be
 629      * reopened.
 630      *
 631      * <p> If this file has an associated channel then the channel is closed
 632      * as well.
 633      *
 634      * @throws     IOException  if an I/O error occurs.
 635      *
 636      * @revised 1.4
 637      */
 638     public void close() throws IOException {
 639         if (closed) {
 640             return;
 641         }
 642         synchronized (closeLock) {
 643             if (closed) {

  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 
  30 import jdk.internal.access.JavaIORandomAccessFileAccess;
  31 import jdk.internal.access.SharedSecrets;
  32 import jdk.internal.misc.Blocker;
  33 import sun.nio.ch.FileChannelImpl;
  34 
  35 
  36 /**
  37  * Instances of this class support both reading and writing to a
  38  * random access file. A random access file behaves like a large
  39  * array of bytes stored in the file system. There is a kind of cursor,
  40  * or index into the implied array, called the <em>file pointer</em>;
  41  * input operations read bytes starting at the file pointer and advance
  42  * the file pointer past the bytes read. If the random access file is
  43  * created in read/write mode, then output operations are also available;
  44  * output operations write bytes starting at the file pointer and advance
  45  * the file pointer past the bytes written. Output operations that write
  46  * past the current end of the implied array cause the array to be
  47  * extended. The file pointer can be read by the
  48  * {@code getFilePointer} method and set by the {@code seek}
  49  * method.
  50  * <p>
  51  * It is generally true of all the reading routines in this class that
  52  * if end-of-file is reached before the desired number of bytes has been

 323      *
 324      * @param name the name of the file
 325      * @param mode the mode flags, a combination of the O_ constants
 326      *             defined above
 327      */
 328     private native void open0(String name, int mode)
 329         throws FileNotFoundException;
 330 
 331     // wrap native call to allow instrumentation
 332     /**
 333      * Opens a file and returns the file descriptor.  The file is
 334      * opened in read-write mode if the O_RDWR bit in {@code mode}
 335      * is true, else the file is opened as read-only.
 336      * If the {@code name} refers to a directory, an IOException
 337      * is thrown.
 338      *
 339      * @param name the name of the file
 340      * @param mode the mode flags, a combination of the O_ constants
 341      *             defined above
 342      */
 343     private void open(String name, int mode) throws FileNotFoundException {
 344         if (Thread.currentThread().isVirtual()) {
 345             Blocker.managedBlock(() -> open0(name, mode));
 346         } else {
 347             open0(name, mode);
 348         }
 349     }
 350 
 351     // 'Read' primitives
 352 
 353     /**
 354      * Reads a byte of data from this file. The byte is returned as an
 355      * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This
 356      * method blocks if no input is yet available.
 357      * <p>
 358      * Although {@code RandomAccessFile} is not a subclass of
 359      * {@code InputStream}, this method behaves in exactly the same
 360      * way as the {@link InputStream#read()} method of
 361      * {@code InputStream}.
 362      *
 363      * @return     the next byte of data, or {@code -1} if the end of the
 364      *             file has been reached.
 365      * @throws     IOException  if an I/O error occurs. Not thrown if
 366      *                          end-of-file has been reached.
 367      */
 368     public int read() throws IOException {
 369         if (Thread.currentThread().isVirtual()) {
 370             return Blocker.managedBlock(() -> read0());
 371         } else {
 372             return read0();
 373         }
 374     }
 375 
 376     private native int read0() throws IOException;
 377 
 378     /**
 379      * Reads a sub array as a sequence of bytes.
 380      * @param     b the buffer into which the data is read.
 381      * @param     off the start offset of the data.
 382      * @param     len the number of bytes to read.
 383      * @throws    IOException If an I/O error has occurred.
 384      */
 385     private int readBytes(byte[] b, int off, int len) throws IOException {
 386         if (Thread.currentThread().isVirtual()) {
 387             return Blocker.managedBlock(() -> readBytes0(b, off, len));
 388         } else {
 389             return readBytes0(b, off, len);
 390         }
 391     }
 392 
 393     private native int readBytes0(byte[] b, int off, int len) throws IOException;
 394 
 395     /**
 396      * Reads up to {@code len} bytes of data from this file into an
 397      * array of bytes. This method blocks until at least one byte of input
 398      * is available.
 399      * <p>
 400      * Although {@code RandomAccessFile} is not a subclass of
 401      * {@code InputStream}, this method behaves in exactly the
 402      * same way as the {@link InputStream#read(byte[], int, int)} method of
 403      * {@code InputStream}.
 404      *
 405      * @param      b     the buffer into which the data is read.
 406      * @param      off   the start offset in array {@code b}
 407      *                   at which the data is written.
 408      * @param      len   the maximum number of bytes read.
 409      * @return     the total number of bytes read into the buffer, or
 410      *             {@code -1} if there is no more data because the end of
 411      *             the file has been reached.
 412      * @throws     IOException If the first byte cannot be read for any reason
 413      *             other than end of file, or if the random access file has been closed,
 414      *             or if some other I/O error occurs.
 415      * @throws     NullPointerException If {@code b} is {@code null}.
 416      * @throws     IndexOutOfBoundsException If {@code off} is negative,
 417      *             {@code len} is negative, or {@code len} is greater than
 418      *             {@code b.length - off}
 419      */
 420     public int read(byte[] b, int off, int len) throws IOException {
 421         if (Thread.currentThread().isVirtual()) {
 422             return Blocker.managedBlock(() -> readBytes(b, off, len));
 423         } else {
 424             return readBytes(b, off, len);
 425         }
 426     }
 427 
 428     /**
 429      * Reads up to {@code b.length} bytes of data from this file
 430      * into an array of bytes. This method blocks until at least one byte
 431      * of input is available.
 432      * <p>
 433      * Although {@code RandomAccessFile} is not a subclass of
 434      * {@code InputStream}, this method behaves in exactly the
 435      * same way as the {@link InputStream#read(byte[])} method of
 436      * {@code InputStream}.
 437      *
 438      * @param      b   the buffer into which the data is read.
 439      * @return     the total number of bytes read into the buffer, or
 440      *             {@code -1} if there is no more data because the end of
 441      *             this file has been reached.
 442      * @throws     IOException If the first byte cannot be read for any reason
 443      *             other than end of file, or if the random access file has been closed,
 444      *             or if some other I/O error occurs.
 445      * @throws     NullPointerException If {@code b} is {@code null}.
 446      */
 447     public int read(byte[] b) throws IOException {
 448         return read(b, 0, b.length);
 449     }
 450 
 451     /**
 452      * Reads {@code b.length} bytes from this file into the byte
 453      * array, starting at the current file pointer. This method reads
 454      * repeatedly from the file until the requested number of bytes are
 455      * read. This method blocks until the requested number of bytes are
 456      * read, the end of the stream is detected, or an exception is thrown.
 457      *
 458      * @param   b   the buffer into which the data is read.
 459      * @throws  NullPointerException if {@code b} is {@code null}.
 460      * @throws  EOFException  if this file reaches the end before reading
 461      *              all the bytes.
 462      * @throws  IOException   if an I/O error occurs.
 463      */
 464     public final void readFully(byte[] b) throws IOException {
 465         readFully(b, 0, b.length);
 466     }
 467 
 468     /**

 522         newpos = pos + n;
 523         if (newpos > len) {
 524             newpos = len;
 525         }
 526         seek(newpos);
 527 
 528         /* return the actual number of bytes skipped */
 529         return (int) (newpos - pos);
 530     }
 531 
 532     // 'Write' primitives
 533 
 534     /**
 535      * Writes the specified byte to this file. The write starts at
 536      * the current file pointer.
 537      *
 538      * @param      b   the {@code byte} to be written.
 539      * @throws     IOException  if an I/O error occurs.
 540      */
 541     public void write(int b) throws IOException {
 542         if (Thread.currentThread().isVirtual()) {
 543             Blocker.managedBlock(() -> write0(b));
 544         } else {
 545             write0(b);
 546         }
 547     }
 548 
 549     private native void write0(int b) throws IOException;
 550 
 551     /**
 552      * Writes a sub array as a sequence of bytes.
 553      *
 554      * @param     b the data to be written
 555      * @param     off the start offset in the data
 556      * @param     len the number of bytes that are written
 557      * @throws    IOException If an I/O error has occurred.
 558      */
 559     private void writeBytes(byte[] b, int off, int len) throws IOException {
 560         if (Thread.currentThread().isVirtual()) {
 561             Blocker.managedBlock(() -> writeBytes0(b, off, len));
 562         } else {
 563             writeBytes0(b, off, len);
 564         }
 565     }
 566 
 567     private native void writeBytes0(byte[] b, int off, int len) throws IOException;
 568 
 569     /**
 570      * Writes {@code b.length} bytes from the specified byte array
 571      * to this file, starting at the current file pointer.
 572      *
 573      * @param      b   the data.
 574      * @throws     IOException  if an I/O error occurs.
 575      */
 576     public void write(byte[] b) throws IOException {
 577         write(b, 0, b.length);
 578     }
 579 
 580     /**
 581      * Writes {@code len} bytes from the specified byte array
 582      * starting at offset {@code off} to this file.
 583      *
 584      * @param      b     the data.
 585      * @param      off   the start offset in the data.
 586      * @param      len   the number of bytes to write.
 587      * @throws     IOException  if an I/O error occurs.
 588      */
 589     public void write(byte[] b, int off, int len) throws IOException {
 590         writeBytes(b, off, len);
 591     }
 592 
 593     // 'Random access' stuff
 594 
 595     /**
 596      * Returns the current offset in this file.
 597      *

 601      */
 602     public native long getFilePointer() throws IOException;
 603 
 604     /**
 605      * Sets the file-pointer offset, measured from the beginning of this
 606      * file, at which the next read or write occurs.  The offset may be
 607      * set beyond the end of the file. Setting the offset beyond the end
 608      * of the file does not change the file length.  The file length will
 609      * change only by writing after the offset has been set beyond the end
 610      * of the file.
 611      *
 612      * @param      pos   the offset position, measured in bytes from the
 613      *                   beginning of the file, at which to set the file
 614      *                   pointer.
 615      * @throws     IOException  if {@code pos} is less than
 616      *                          {@code 0} or if an I/O error occurs.
 617      */
 618     public void seek(long pos) throws IOException {
 619         if (pos < 0) {
 620             throw new IOException("Negative seek offset");
 621         }
 622         if (Thread.currentThread().isVirtual()) {
 623             Blocker.managedBlock(() -> seek0(pos));
 624         } else {
 625             seek0(pos);
 626         }
 627     }
 628 
 629     private native void seek0(long pos) throws IOException;
 630 
 631     /**
 632      * Returns the length of this file.
 633      *
 634      * @return     the length of this file, measured in bytes.
 635      * @throws     IOException  if an I/O error occurs.
 636      */
 637     public long length() throws IOException {
 638         if (Thread.currentThread().isVirtual()) {
 639             return Blocker.managedBlock(() -> length0());
 640         } else {
 641             return length0();
 642         }
 643     }
 644 
 645     private native long length0() throws IOException;
 646 
 647     /**
 648      * Sets the length of this file.
 649      *
 650      * <p> If the present length of the file as returned by the
 651      * {@code length} method is greater than the {@code newLength}
 652      * argument then the file will be truncated.  In this case, if the file
 653      * offset as returned by the {@code getFilePointer} method is greater
 654      * than {@code newLength} then after this method returns the offset
 655      * will be equal to {@code newLength}.
 656      *
 657      * <p> If the present length of the file as returned by the
 658      * {@code length} method is smaller than the {@code newLength}
 659      * argument then the file will be extended.  In this case, the contents of
 660      * the extended portion of the file are not defined.
 661      *
 662      * @param      newLength    The desired length of the file
 663      * @throws     IOException  If an I/O error occurs
 664      * @since      1.2
 665      */
 666     public void setLength(long newLength) throws IOException {
 667         if (Thread.currentThread().isVirtual()) {
 668             Blocker.managedBlock(() -> setLength0(newLength));
 669         } else {
 670             setLength0(newLength);
 671         }
 672     }
 673 
 674     private native void setLength0(long newLength) throws IOException;
 675 
 676     /**
 677      * Closes this random access file stream and releases any system
 678      * resources associated with the stream. A closed random access
 679      * file cannot perform input or output operations and cannot be
 680      * reopened.
 681      *
 682      * <p> If this file has an associated channel then the channel is closed
 683      * as well.
 684      *
 685      * @throws     IOException  if an I/O error occurs.
 686      *
 687      * @revised 1.4
 688      */
 689     public void close() throws IOException {
 690         if (closed) {
 691             return;
 692         }
 693         synchronized (closeLock) {
 694             if (closed) {
< prev index next >