< 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 >