< prev index next >
src/java.base/share/classes/java/io/FileOutputStream.java
Print this page
@@ -77,10 +77,14 @@
*/
private final String path;
private final AtomicBoolean closed = new AtomicBoolean(false);
+ private boolean direct = false;
+
+ private int pageSize = -1;
+
/**
* Creates a file output stream to write to the file with the
* specified name. A new <code>FileDescriptor</code> object is
* created to represent this file connection.
* <p>
@@ -99,11 +103,11 @@
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(String name) throws FileNotFoundException {
- this(name != null ? new File(name) : null, false);
+ this(name != null ? new File(name) : null, false, false);
}
/**
* Creates a file output stream to write to the file with the specified
* name. If the second argument is <code>true</code>, then
@@ -131,11 +135,46 @@
* @since 1.1
*/
public FileOutputStream(String name, boolean append)
throws FileNotFoundException
{
- this(name != null ? new File(name) : null, append);
+ this(name != null ? new File(name) : null, append, false);
+ }
+
+ /**
+ * Creates a file output stream to write to the file with the specified
+ * name. If the second argument is <code>true</code>, then bytes will
+ * be written to the end of the file rather than the beginning. If the
+ * third parameter is <code>true</code>, then bytes will be directly
+ * written to storage media. A new <code>FileDescriptor</code> object
+ * is created to represent this file connection.
+ * <p>
+ * First, if there is a security manager, its <code>checkWrite</code>
+ * method is called with <code>name</code> as its argument.
+ * <p>
+ * If the file exists but is a directory rather than a regular file, does
+ * not exist but cannot be created, or cannot be opened for any other
+ * reason then a <code>FileNotFoundException</code> is thrown.
+ *
+ * @param name the system-dependent file name
+ * @param append if <code>true</code>, then bytes will be written
+ * to the end of the file rather than the beginning
+ * @param direct if <code>true</code>, then bytes will be written
+ * directly to storage media
+ * @exception FileNotFoundException if the file exists but is a directory
+ * rather than a regular file, does not exist but cannot
+ * be created, or cannot be opened for any other reason.
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkWrite</code> method denies write access
+ * to the file.
+ * @see java.lang.SecurityManager#checkWrite(java.lang.String)
+ * @since 1.9
+ */
+ public FileOutputStream(String name, boolean append, boolean direct)
+ throws FileNotFoundException
+ {
+ this(name != null ? new File(name) : null, append, direct);
}
/**
* Creates a file output stream to write to the file represented by
* the specified <code>File</code> object. A new
@@ -160,11 +199,11 @@
* @see java.io.File#getPath()
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(File file) throws FileNotFoundException {
- this(file, false);
+ this(file, false, false);
}
/**
* Creates a file output stream to write to the file represented by
* the specified <code>File</code> object. If the second argument is
@@ -195,10 +234,53 @@
* @since 1.4
*/
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
+ this(file, append, false);
+ }
+
+ /**
+ * Creates a file output stream to write to the file represented by
+ * the specified <code>File</code> object. If the second argument is
+ * <code>true</code>, then bytes will be written to the end of the file
+ * rather than the beginning. If the third argument is <code>true</code>,
+ * then bytes will be directly written to storage media. A new
+ * <code>FileDescriptor</code> object is created to represent this file
+ * connection.
+ * <p>
+ * First, if there is a security manager, its <code>checkWrite</code>
+ * method is called with the path represented by the <code>file</code>
+ * argument as its argument.
+ * <p>
+ * If the file exists but is a directory rather than a regular file, does
+ * not exist but cannot be created, or cannot be opened for any other
+ * reason then a <code>FileNotFoundException</code> is thrown.
+ *
+ * @param file the file to be opened for writing.
+ * @param append if <code>true</code>, then bytes will be written
+ * to the end of the file rather than the beginning
+ * @param direct if <code>true</code>, then bytes will be written
+ * directly to storage media
+ * @exception FileNotFoundException if the file exists but is a directory
+ * rather than a regular file, does not exist but cannot
+ * be created, or cannot be opened for any other reason
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkWrite</code> method denies write access
+ * to the file.
+ * @see java.io.File#getPath()
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkWrite(java.lang.String)
+ * @since 1.9
+ */
+ public FileOutputStream(File file, boolean append, boolean direct)
+ throws FileNotFoundException
+ {
+ this.direct = direct;
+ if (direct) {
+ getPageSize();
+ }
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
@@ -254,23 +336,33 @@
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
+ * @param direct whether the file s to be opened in the direct mode
*/
- private native void open0(String name, boolean append)
+ private native void open0(String name, boolean append, boolean direct)
throws FileNotFoundException;
// wrap native call to allow instrumentation
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private void open(String name, boolean append)
throws FileNotFoundException {
- open0(name, append);
+ open0(name, append, direct);
+ }
+
+ private native int getPageSize0();
+
+ private int getPageSize() {
+ if (pageSize == -1) {
+ pageSize = getPageSize0();
+ }
+ return this.pageSize;
}
/**
* Writes the specified byte to this file output stream.
*
@@ -302,19 +394,38 @@
*/
private native void writeBytes(byte b[], int off, int len, boolean append)
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
+ * @param append {@code true} to first advance the position to the
+ * end of file
+ * @exception IOException If an I/O error has occurred.*/
+ private native void writeBytesD(byte b[], int off, int len, boolean append)
+ throws IOException;
+
+ /**
* Writes <code>b.length</code> bytes from the specified byte array
* to this file output stream.
*
* @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 must be aligned "
+ + "with kernel page size " + pageSize + " bytes!");
+ }
+ writeBytesD(b, 0, b.length, fdAccess.getAppend(fd));
+ } else {
writeBytes(b, 0, b.length, fdAccess.getAppend(fd));
}
+ }
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this file output stream.
*
@@ -322,12 +433,26 @@
* @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 the start "
+ + "point must be aligned with kernel page size " + pageSize + " bytes!");
+ }
+ writeBytesD(b, off, len, fdAccess.getAppend(fd));
+ } else {
writeBytes(b, off, len, fdAccess.getAppend(fd));
}
+ }
+
+ private long getCurrentLocation() throws IOException {
+ return getCurrentLocation0();
+ }
+
+ private native long getCurrentLocation0() throws IOException;
/**
* Closes this file output stream and releases any system resources
* associated with this stream. This file output stream may no longer
* be used for writing bytes.
< prev index next >