src/share/classes/java/io/FileOutputStream.java

Print this page




  46  * @see     java.io.File
  47  * @see     java.io.FileDescriptor
  48  * @see     java.io.FileInputStream
  49  * @see     java.nio.file.Files#newOutputStream
  50  * @since   JDK1.0
  51  */
  52 public
  53 class FileOutputStream extends OutputStream
  54 {
  55     /**
  56      * The system dependent file descriptor.
  57      */
  58     private final FileDescriptor fd;
  59 
  60     /**
  61      * True if the file is opened for append.
  62      */
  63     private final boolean append;
  64 
  65     /**
  66      * The associated channel, initalized lazily.
  67      */
  68     private FileChannel channel;
  69 
  70     private final Object closeLock = new Object();
  71     private volatile boolean closed = false;
  72     private static final ThreadLocal<Boolean> runningFinalize =
  73         new ThreadLocal<>();
  74 
  75     private static boolean isRunningFinalize() {
  76         Boolean val;
  77         if ((val = runningFinalize.get()) != null)
  78             return val.booleanValue();
  79         return false;
  80     }
  81 
  82     /**
  83      * Creates a file output stream to write to the file with the
  84      * specified name. A new <code>FileDescriptor</code> object is
  85      * created to represent this file connection.
  86      * <p>
  87      * First, if there is a security manager, its <code>checkWrite</code>
  88      * method is called with <code>name</code> as its argument.
  89      * <p>
  90      * If the file exists but is a directory rather than a regular file, does
  91      * not exist but cannot be created, or cannot be opened for any other
  92      * reason then a <code>FileNotFoundException</code> is thrown.
  93      *
  94      * @param      name   the system-dependent filename
  95      * @exception  FileNotFoundException  if the file exists but is a directory
  96      *                   rather than a regular file, does not exist but cannot
  97      *                   be created, or cannot be opened for any other reason
  98      * @exception  SecurityException  if a security manager exists and its
  99      *               <code>checkWrite</code> method denies write access
 100      *               to the file.
 101      * @see        java.lang.SecurityManager#checkWrite(java.lang.String)


 338             }
 339             closed = true;
 340         }
 341 
 342         if (channel != null) {
 343             /*
 344              * Decrement FD use count associated with the channel
 345              * The use count is incremented whenever a new channel
 346              * is obtained from this stream.
 347              */
 348             fd.decrementAndGetUseCount();
 349             channel.close();
 350         }
 351 
 352         /*
 353          * Decrement FD use count associated with this stream
 354          */
 355         int useCount = fd.decrementAndGetUseCount();
 356 
 357         /*
 358          * If FileDescriptor is still in use by another stream, the finalizer
 359          * will not close it.
 360          */
 361         if ((useCount <= 0) || !isRunningFinalize()) {
 362             close0();
 363         }
 364     }
 365 
 366     /**
 367      * Returns the file descriptor associated with this stream.
 368      *
 369      * @return  the <code>FileDescriptor</code> object that represents
 370      *          the connection to the file in the file system being used
 371      *          by this <code>FileOutputStream</code> object.
 372      *
 373      * @exception  IOException  if an I/O error occurs.
 374      * @see        java.io.FileDescriptor
 375      */
 376      public final FileDescriptor getFD()  throws IOException {
 377         if (fd != null) return fd;
 378         throw new IOException();
 379      }
 380 
 381     /**


 407                  */
 408                 fd.incrementAndGetUseCount();
 409             }
 410             return channel;
 411         }
 412     }
 413 
 414     /**
 415      * Cleans up the connection to the file, and ensures that the
 416      * <code>close</code> method of this file output stream is
 417      * called when there are no more references to this stream.
 418      *
 419      * @exception  IOException  if an I/O error occurs.
 420      * @see        java.io.FileInputStream#close()
 421      */
 422     protected void finalize() throws IOException {
 423         if (fd != null) {
 424             if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
 425                 flush();
 426             } else {
 427 
 428                 /*
 429                  * Finalizer should not release the FileDescriptor if another
 430                  * stream is still using it. If the user directly invokes
 431                  * close() then the FileDescriptor is also released.
 432                  */
 433                 runningFinalize.set(Boolean.TRUE);
 434                 try {
 435                     close();
 436                 } finally {
 437                     runningFinalize.set(Boolean.FALSE);
 438                 }
 439             }
 440         }
 441     }
 442 
 443     private native void close0() throws IOException;
 444 
 445     private static native void initIDs();
 446 
 447     static {
 448         initIDs();
 449     }
 450 
 451 }


  46  * @see     java.io.File
  47  * @see     java.io.FileDescriptor
  48  * @see     java.io.FileInputStream
  49  * @see     java.nio.file.Files#newOutputStream
  50  * @since   JDK1.0
  51  */
  52 public
  53 class FileOutputStream extends OutputStream
  54 {
  55     /**
  56      * The system dependent file descriptor.
  57      */
  58     private final FileDescriptor fd;
  59 
  60     /**
  61      * True if the file is opened for append.
  62      */
  63     private final boolean append;
  64 
  65     /**
  66      * The associated channel, initialized lazily.
  67      */
  68     private FileChannel channel;
  69 
  70     private final Object closeLock = new Object();
  71     private volatile boolean closed = false;


  72 







  73     /**
  74      * Creates a file output stream to write to the file with the
  75      * specified name. A new <code>FileDescriptor</code> object is
  76      * created to represent this file connection.
  77      * <p>
  78      * First, if there is a security manager, its <code>checkWrite</code>
  79      * method is called with <code>name</code> as its argument.
  80      * <p>
  81      * If the file exists but is a directory rather than a regular file, does
  82      * not exist but cannot be created, or cannot be opened for any other
  83      * reason then a <code>FileNotFoundException</code> is thrown.
  84      *
  85      * @param      name   the system-dependent filename
  86      * @exception  FileNotFoundException  if the file exists but is a directory
  87      *                   rather than a regular file, does not exist but cannot
  88      *                   be created, or cannot be opened for any other reason
  89      * @exception  SecurityException  if a security manager exists and its
  90      *               <code>checkWrite</code> method denies write access
  91      *               to the file.
  92      * @see        java.lang.SecurityManager#checkWrite(java.lang.String)


 329             }
 330             closed = true;
 331         }
 332 
 333         if (channel != null) {
 334             /*
 335              * Decrement FD use count associated with the channel
 336              * The use count is incremented whenever a new channel
 337              * is obtained from this stream.
 338              */
 339             fd.decrementAndGetUseCount();
 340             channel.close();
 341         }
 342 
 343         /*
 344          * Decrement FD use count associated with this stream
 345          */
 346         int useCount = fd.decrementAndGetUseCount();
 347 
 348         /*
 349          * If FileDescriptor is still in use by another stream, we
 350          * will not close it.
 351          */
 352         if (useCount <= 0) {
 353             close0();
 354         }
 355     }
 356 
 357     /**
 358      * Returns the file descriptor associated with this stream.
 359      *
 360      * @return  the <code>FileDescriptor</code> object that represents
 361      *          the connection to the file in the file system being used
 362      *          by this <code>FileOutputStream</code> object.
 363      *
 364      * @exception  IOException  if an I/O error occurs.
 365      * @see        java.io.FileDescriptor
 366      */
 367      public final FileDescriptor getFD()  throws IOException {
 368         if (fd != null) return fd;
 369         throw new IOException();
 370      }
 371 
 372     /**


 398                  */
 399                 fd.incrementAndGetUseCount();
 400             }
 401             return channel;
 402         }
 403     }
 404 
 405     /**
 406      * Cleans up the connection to the file, and ensures that the
 407      * <code>close</code> method of this file output stream is
 408      * called when there are no more references to this stream.
 409      *
 410      * @exception  IOException  if an I/O error occurs.
 411      * @see        java.io.FileInputStream#close()
 412      */
 413     protected void finalize() throws IOException {
 414         if (fd != null) {
 415             if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
 416                 flush();
 417             } else {








 418                     close();


 419             }
 420         }

 421     }
 422 
 423     private native void close0() throws IOException;
 424 
 425     private static native void initIDs();
 426 
 427     static {
 428         initIDs();
 429     }
 430 
 431 }