< prev index next >

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

Print this page

        

@@ -62,10 +62,12 @@
 public class RandomAccessFile implements DataOutput, DataInput, Closeable {
 
     private FileDescriptor fd;
     private volatile FileChannel channel;
     private boolean rw;
+    private boolean direct = false;
+    private int pageSize = -1;
 
     /**
      * The path of the referenced file
      * (null if the stream is created with a file descriptor)
      */

@@ -76,10 +78,11 @@
     private static final int O_RDONLY = 1;
     private static final int O_RDWR =   2;
     private static final int O_SYNC =   4;
     private static final int O_DSYNC =  8;
     private static final int O_TEMPORARY =  16;
+    private static final int O_DIRECT = 32;
 
     /**
      * Creates a random access file stream to read from, and optionally
      * to write to, a file with the specified name. A new
      * {@link FileDescriptor} object is created to represent the

@@ -214,29 +217,39 @@
     {
         String name = (file != null ? file.getPath() : null);
         int imode = -1;
         if (mode.equals("r"))
             imode = O_RDONLY;
+        else if (mode.equals("ro")) {
+            imode = O_RDONLY | O_DIRECT;
+            direct = true;
+            getPageSize();
+        }
         else if (mode.startsWith("rw")) {
             imode = O_RDWR;
             rw = true;
             if (mode.length() > 2) {
                 if (mode.equals("rws"))
                     imode |= O_SYNC;
                 else if (mode.equals("rwd"))
                     imode |= O_DSYNC;
+                else if (mode.equals("rwo")) {
+                    imode |= O_DIRECT;
+                    direct = true;
+                    getPageSize();
+                }
                 else
                     imode = -1;
             }
         }
         if (openAndDelete)
             imode |= O_TEMPORARY;
         if (imode < 0)
             throw new IllegalArgumentException("Illegal mode \"" + mode
                                                + "\" must be one of "
-                                               + "\"r\", \"rw\", \"rws\","
-                                               + " or \"rwd\"");
+                                               + "\"r\", \"ro\", \"rw\", \"rws\", \"rwd\""
+                                               + " or \"rwo\"");
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkRead(name);
             if (rw) {
                 security.checkWrite(name);

@@ -336,10 +349,19 @@
     private void open(String name, int mode)
         throws FileNotFoundException {
         open0(name, mode);
     }
 
+    private native int getPageSize0();
+
+    private int getPageSize() {
+        if (pageSize == -1) {
+            pageSize = getPageSize0();
+        }
+        return this.pageSize;
+    }
+
     // 'Read' primitives
 
     /**
      * Reads a byte of data from this file. The byte is returned as an
      * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This

@@ -369,10 +391,19 @@
      * @exception IOException If an I/O error has occurred.
      */
     private native int readBytes(byte b[], int off, int len) throws IOException;
 
     /**
+     * Reads a sub array as a sequence of bytes with DirectIO.
+     * @param b the buffer into which the data is read.
+     * @param off the start offset of the data.
+     * @param len the number of bytes to read.
+     * @exception IOException If an I/O error has occurred.
+     */
+    private native int readBytesD(byte b[], int off, int len) throws IOException;
+
+    /**
      * Reads up to {@code len} bytes of data from this file into an
      * array of bytes. This method blocks until at least one byte of input
      * is available.
      * <p>
      * Although {@code RandomAccessFile} is not a subclass of

@@ -394,10 +425,13 @@
      * @exception  IndexOutOfBoundsException If {@code off} is negative,
      * {@code len} is negative, or {@code len} is greater than
      * {@code b.length - off}
      */
     public int read(byte b[], int off, int len) throws IOException {
+        if (direct) {
+            return readBytesD(b, off, len);
+        }
         return readBytes(b, off, len);
     }
 
     /**
      * Reads up to {@code b.length} bytes of data from this file

@@ -417,10 +451,13 @@
      * other than end of file, or if the random access file has been closed, or if
      * some other I/O error occurs.
      * @exception  NullPointerException If {@code b} is {@code null}.
      */
     public int read(byte b[]) throws IOException {
+        if (direct) {
+            return readBytesD(b, 0, b.length);
+        }
         return readBytes(b, 0, b.length);
     }
 
     /**
      * Reads {@code b.length} bytes from this file into the byte

@@ -527,19 +564,37 @@
      * @exception IOException If an I/O error has occurred.
      */
     private native void writeBytes(byte b[], int off, int len) throws IOException;
 
     /**
+     * Writes a sub array as a sequence of bytes with DirectIO.
+     * @param b the data to be written
+     * @param off the start offset in the data
+     * @param len the number of bytes that are written
+     * @exception IOException If an I/O error has occurred.
+     */
+    private native void writeBytesD(byte b[], int off, int len) throws IOException;
+
+    /**
      * Writes {@code b.length} bytes from the specified byte array
      * to this file, starting at the current file pointer.
      *
      * @param      b   the data.
      * @exception  IOException  if an I/O error occurs.
      */
     public void write(byte b[]) throws IOException {
+        if (direct) {
+            if((b.length % pageSize != 0) && (getCurrentLocation() % pageSize != 0)) {
+                throw new IOException("In DirectIO mode, the IO size and start point "
+                                      + "must be aligned with kernel page size " + pageSize + " bytes!"); 
+            } else {
+                writeBytesD(b, 0, b.length);
+            }
+        } else {
         writeBytes(b, 0, b.length);
     }
+    }
 
     /**
      * Writes {@code len} bytes from the specified byte array
      * starting at offset {@code off} to this file.
      *

@@ -547,12 +602,21 @@
      * @param      off   the start offset in the data.
      * @param      len   the number of bytes to write.
      * @exception  IOException  if an I/O error occurs.
      */
     public void write(byte b[], int off, int len) throws IOException {
+        if (direct) {
+            if ((len % pageSize != 0) || (getCurrentLocation() % pageSize != 0)) {
+                throw new IOException("In DirectIO mode, the IO size and start point "
+                                      + "must be aligned with kernel page size " + pageSize + " bytes!");
+            } else {
+                writeBytesD(b, off, len);
+            }
+        } else {
         writeBytes(b, off, len);
     }
+    }
 
     // 'Random access' stuff
 
     /**
      * Returns the current offset in this file.

@@ -585,10 +649,16 @@
         }
     }
 
     private native void seek0(long pos) throws IOException;
 
+    private long getCurrentLocation() throws IOException {
+        return getCurrentLocation0();
+    }
+
+    private native long getCurrentLocation0() throws IOException;
+
     /**
      * Returns the length of this file.
      *
      * @return     the length of this file, measured in bytes.
      * @exception  IOException  if an I/O error occurs.
< prev index next >