< prev index next >

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

Print this page

 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package java.io;
 27 
 28 import java.nio.channels.FileChannel;
 29 import jdk.internal.access.SharedSecrets;
 30 import jdk.internal.access.JavaIOFileDescriptorAccess;
 31 import jdk.internal.misc.Blocker;
 32 import sun.nio.ch.FileChannelImpl;
 33 
 34 
 35 /**
 36  * A file output stream is an output stream for writing data to a
 37  * {@code File} or to a {@code FileDescriptor}. Whether or not
 38  * a file is available or may be created depends upon the underlying
 39  * platform.  Some platforms, in particular, allow a file to be opened
 40  * for writing by only one {@code FileOutputStream} (or other
 41  * file-writing object) at a time.  In such situations the constructors in
 42  * this class will fail if the file involved is already open.
 43  *
 44  * <p>{@code FileOutputStream} is meant for writing streams of raw bytes
 45  * such as image data. For writing streams of characters, consider using
 46  * {@code FileWriter}.
 47  *
 48  * @apiNote
 49  * The {@link #close} method should be called to release resources used by this
 50  * stream, either directly, or with the {@code try}-with-resources statement.
 51  *

269         this.path = null;
270 
271         fd.attach(this);
272     }
273 
274     /**
275      * Opens a file, with the specified name, for overwriting or appending.
276      * @param name name of file to be opened
277      * @param append whether the file is to be opened in append mode
278      */
279     private native void open0(String name, boolean append)
280         throws FileNotFoundException;
281 
282     // wrap native call to allow instrumentation
283     /**
284      * Opens a file, with the specified name, for overwriting or appending.
285      * @param name name of file to be opened
286      * @param append whether the file is to be opened in append mode
287      */
288     private void open(String name, boolean append) throws FileNotFoundException {
289         long comp = Blocker.begin();
290         try {
291             open0(name, append);
292         } finally {
293             Blocker.end(comp);
294         }
295     }
296 
297     /**
298      * Writes the specified byte to this file output stream.
299      *
300      * @param   b   the byte to be written.
301      * @param   append   {@code true} if the write operation first
302      *     advances the position to the end of file
303      */
304     private native void write(int b, boolean append) throws IOException;
305 
306     /**
307      * Writes the specified byte to this file output stream. Implements
308      * the {@code write} method of {@code OutputStream}.
309      *
310      * @param      b   the byte to be written.
311      * @throws     IOException  if an I/O error occurs.
312      */
313     @Override
314     public void write(int b) throws IOException {
315         boolean append = FD_ACCESS.getAppend(fd);
316         long comp = Blocker.begin();
317         try {
318             write(b, append);
319         } finally {
320             Blocker.end(comp);
321         }
322     }
323 
324     /**
325      * Writes a sub array as a sequence of bytes.
326      * @param b the data to be written
327      * @param off the start offset in the data
328      * @param len the number of bytes that are written
329      * @param append {@code true} to first advance the position to the
330      *     end of file
331      * @throws    IOException If an I/O error has occurred.
332      */
333     private native void writeBytes(byte[] b, int off, int len, boolean append)
334         throws IOException;
335 
336     /**
337      * Writes {@code b.length} bytes from the specified byte array
338      * to this file output stream.
339      *
340      * @param      b   {@inheritDoc}
341      * @throws     IOException  {@inheritDoc}
342      */
343     @Override
344     public void write(byte[] b) throws IOException {
345         boolean append = FD_ACCESS.getAppend(fd);
346         long comp = Blocker.begin();
347         try {
348             writeBytes(b, 0, b.length, append);
349         } finally {
350             Blocker.end(comp);
351         }
352     }
353 
354     /**
355      * Writes {@code len} bytes from the specified byte array
356      * starting at offset {@code off} to this file output stream.
357      *
358      * @param      b     {@inheritDoc}
359      * @param      off   {@inheritDoc}
360      * @param      len   {@inheritDoc}
361      * @throws     IOException  if an I/O error occurs.
362      * @throws     IndexOutOfBoundsException {@inheritDoc}
363      */
364     @Override
365     public void write(byte[] b, int off, int len) throws IOException {
366         boolean append = FD_ACCESS.getAppend(fd);
367         long comp = Blocker.begin();
368         try {
369             writeBytes(b, off, len, append);
370         } finally {
371             Blocker.end(comp);
372         }
373     }
374 
375     /**
376      * Closes this file output stream and releases any system resources
377      * associated with this stream. This file output stream may no longer
378      * be used for writing bytes.
379      *
380      * <p> If this stream has an associated channel then the channel is closed
381      * as well.
382      *
383      * @apiNote
384      * Overriding {@link #close} to perform cleanup actions is reliable
385      * only when called directly or when called by try-with-resources.
386      *
387      * @implSpec
388      * Subclasses requiring that resource cleanup take place after a stream becomes
389      * unreachable should use the {@link java.lang.ref.Cleaner} mechanism.
390      *
391      * <p>
392      * If this stream has an associated channel then this method will close the

443      * object associated with this file output stream.
444      *
445      * <p> The initial {@link java.nio.channels.FileChannel#position()
446      * position} of the returned channel will be equal to the
447      * number of bytes written to the file so far unless this stream is in
448      * append mode, in which case it will be equal to the size of the file.
449      * Writing bytes to this stream will increment the channel's position
450      * accordingly.  Changing the channel's position, either explicitly or by
451      * writing, will change this stream's file position.
452      *
453      * @return  the file channel associated with this file output stream
454      *
455      * @since 1.4
456      */
457     public FileChannel getChannel() {
458         FileChannel fc = this.channel;
459         if (fc == null) {
460             synchronized (this) {
461                 fc = this.channel;
462                 if (fc == null) {
463                     this.channel = fc = FileChannelImpl.open(fd, path, false,
464                         true, false, this);
465                     if (closed) {
466                         try {
467                             // possible race with close(), benign since
468                             // FileChannel.close is final and idempotent
469                             fc.close();
470                         } catch (IOException ioe) {
471                             throw new InternalError(ioe); // should not happen
472                         }
473                     }
474                 }
475             }
476         }
477         return fc;
478     }
479 
480     private static native void initIDs();
481 
482     static {
483         initIDs();
484     }

 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package java.io;
 27 
 28 import java.nio.channels.FileChannel;
 29 import jdk.internal.access.SharedSecrets;
 30 import jdk.internal.access.JavaIOFileDescriptorAccess;

 31 import sun.nio.ch.FileChannelImpl;
 32 
 33 
 34 /**
 35  * A file output stream is an output stream for writing data to a
 36  * {@code File} or to a {@code FileDescriptor}. Whether or not
 37  * a file is available or may be created depends upon the underlying
 38  * platform.  Some platforms, in particular, allow a file to be opened
 39  * for writing by only one {@code FileOutputStream} (or other
 40  * file-writing object) at a time.  In such situations the constructors in
 41  * this class will fail if the file involved is already open.
 42  *
 43  * <p>{@code FileOutputStream} is meant for writing streams of raw bytes
 44  * such as image data. For writing streams of characters, consider using
 45  * {@code FileWriter}.
 46  *
 47  * @apiNote
 48  * The {@link #close} method should be called to release resources used by this
 49  * stream, either directly, or with the {@code try}-with-resources statement.
 50  *

268         this.path = null;
269 
270         fd.attach(this);
271     }
272 
273     /**
274      * Opens a file, with the specified name, for overwriting or appending.
275      * @param name name of file to be opened
276      * @param append whether the file is to be opened in append mode
277      */
278     private native void open0(String name, boolean append)
279         throws FileNotFoundException;
280 
281     // wrap native call to allow instrumentation
282     /**
283      * Opens a file, with the specified name, for overwriting or appending.
284      * @param name name of file to be opened
285      * @param append whether the file is to be opened in append mode
286      */
287     private void open(String name, boolean append) throws FileNotFoundException {
288         open0(name, append);





289     }
290 
291     /**
292      * Writes the specified byte to this file output stream.
293      *
294      * @param   b   the byte to be written.
295      * @param   append   {@code true} if the write operation first
296      *     advances the position to the end of file
297      */
298     private native void write(int b, boolean append) throws IOException;
299 
300     /**
301      * Writes the specified byte to this file output stream. Implements
302      * the {@code write} method of {@code OutputStream}.
303      *
304      * @param      b   the byte to be written.
305      * @throws     IOException  if an I/O error occurs.
306      */
307     @Override
308     public void write(int b) throws IOException {
309         boolean append = FD_ACCESS.getAppend(fd);
310         write(b, append);





311     }
312 
313     /**
314      * Writes a sub array as a sequence of bytes.
315      * @param b the data to be written
316      * @param off the start offset in the data
317      * @param len the number of bytes that are written
318      * @param append {@code true} to first advance the position to the
319      *     end of file
320      * @throws    IOException If an I/O error has occurred.
321      */
322     private native void writeBytes(byte[] b, int off, int len, boolean append)
323         throws IOException;
324 
325     /**
326      * Writes {@code b.length} bytes from the specified byte array
327      * to this file output stream.
328      *
329      * @param      b   {@inheritDoc}
330      * @throws     IOException  {@inheritDoc}
331      */
332     @Override
333     public void write(byte[] b) throws IOException {
334         boolean append = FD_ACCESS.getAppend(fd);
335         writeBytes(b, 0, b.length, append);





336     }
337 
338     /**
339      * Writes {@code len} bytes from the specified byte array
340      * starting at offset {@code off} to this file output stream.
341      *
342      * @param      b     {@inheritDoc}
343      * @param      off   {@inheritDoc}
344      * @param      len   {@inheritDoc}
345      * @throws     IOException  if an I/O error occurs.
346      * @throws     IndexOutOfBoundsException {@inheritDoc}
347      */
348     @Override
349     public void write(byte[] b, int off, int len) throws IOException {
350         boolean append = FD_ACCESS.getAppend(fd);
351         writeBytes(b, off, len, append);





352     }
353 
354     /**
355      * Closes this file output stream and releases any system resources
356      * associated with this stream. This file output stream may no longer
357      * be used for writing bytes.
358      *
359      * <p> If this stream has an associated channel then the channel is closed
360      * as well.
361      *
362      * @apiNote
363      * Overriding {@link #close} to perform cleanup actions is reliable
364      * only when called directly or when called by try-with-resources.
365      *
366      * @implSpec
367      * Subclasses requiring that resource cleanup take place after a stream becomes
368      * unreachable should use the {@link java.lang.ref.Cleaner} mechanism.
369      *
370      * <p>
371      * If this stream has an associated channel then this method will close the

422      * object associated with this file output stream.
423      *
424      * <p> The initial {@link java.nio.channels.FileChannel#position()
425      * position} of the returned channel will be equal to the
426      * number of bytes written to the file so far unless this stream is in
427      * append mode, in which case it will be equal to the size of the file.
428      * Writing bytes to this stream will increment the channel's position
429      * accordingly.  Changing the channel's position, either explicitly or by
430      * writing, will change this stream's file position.
431      *
432      * @return  the file channel associated with this file output stream
433      *
434      * @since 1.4
435      */
436     public FileChannel getChannel() {
437         FileChannel fc = this.channel;
438         if (fc == null) {
439             synchronized (this) {
440                 fc = this.channel;
441                 if (fc == null) {
442                     fc = FileChannelImpl.open(fd, path, false, true, false, false, this);
443                     this.channel = fc;
444                     if (closed) {
445                         try {
446                             // possible race with close(), benign since
447                             // FileChannel.close is final and idempotent
448                             fc.close();
449                         } catch (IOException ioe) {
450                             throw new InternalError(ioe); // should not happen
451                         }
452                     }
453                 }
454             }
455         }
456         return fc;
457     }
458 
459     private static native void initIDs();
460 
461     static {
462         initIDs();
463     }
< prev index next >