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