Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/io/FileOutputStream.java
38829 views
/*1* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.io;2627import java.nio.channels.FileChannel;28import sun.nio.ch.FileChannelImpl;293031/**32* A file output stream is an output stream for writing data to a33* <code>File</code> or to a <code>FileDescriptor</code>. Whether or not34* a file is available or may be created depends upon the underlying35* platform. Some platforms, in particular, allow a file to be opened36* for writing by only one <tt>FileOutputStream</tt> (or other37* file-writing object) at a time. In such situations the constructors in38* this class will fail if the file involved is already open.39*40* <p><code>FileOutputStream</code> is meant for writing streams of raw bytes41* such as image data. For writing streams of characters, consider using42* <code>FileWriter</code>.43*44* @author Arthur van Hoff45* @see java.io.File46* @see java.io.FileDescriptor47* @see java.io.FileInputStream48* @see java.nio.file.Files#newOutputStream49* @since JDK1.050*/51public52class FileOutputStream extends OutputStream53{54/**55* The system dependent file descriptor.56*/57private final FileDescriptor fd;5859/**60* True if the file is opened for append.61*/62private final boolean append;6364/**65* The associated channel, initialized lazily.66*/67private FileChannel channel;6869/**70* The path of the referenced file71* (null if the stream is created with a file descriptor)72*/73private final String path;7475private final Object closeLock = new Object();76private volatile boolean closed = false;7778/**79* Creates a file output stream to write to the file with the80* specified name. A new <code>FileDescriptor</code> object is81* created to represent this file connection.82* <p>83* First, if there is a security manager, its <code>checkWrite</code>84* method is called with <code>name</code> as its argument.85* <p>86* If the file exists but is a directory rather than a regular file, does87* not exist but cannot be created, or cannot be opened for any other88* reason then a <code>FileNotFoundException</code> is thrown.89*90* @param name the system-dependent filename91* @exception FileNotFoundException if the file exists but is a directory92* rather than a regular file, does not exist but cannot93* be created, or cannot be opened for any other reason94* @exception SecurityException if a security manager exists and its95* <code>checkWrite</code> method denies write access96* to the file.97* @see java.lang.SecurityManager#checkWrite(java.lang.String)98*/99public FileOutputStream(String name) throws FileNotFoundException {100this(name != null ? new File(name) : null, false);101}102103/**104* Creates a file output stream to write to the file with the specified105* name. If the second argument is <code>true</code>, then106* bytes will be written to the end of the file rather than the beginning.107* A new <code>FileDescriptor</code> object is created to represent this108* file connection.109* <p>110* First, if there is a security manager, its <code>checkWrite</code>111* method is called with <code>name</code> as its argument.112* <p>113* If the file exists but is a directory rather than a regular file, does114* not exist but cannot be created, or cannot be opened for any other115* reason then a <code>FileNotFoundException</code> is thrown.116*117* @param name the system-dependent file name118* @param append if <code>true</code>, then bytes will be written119* to the end of the file rather than the beginning120* @exception FileNotFoundException if the file exists but is a directory121* rather than a regular file, does not exist but cannot122* be created, or cannot be opened for any other reason.123* @exception SecurityException if a security manager exists and its124* <code>checkWrite</code> method denies write access125* to the file.126* @see java.lang.SecurityManager#checkWrite(java.lang.String)127* @since JDK1.1128*/129public FileOutputStream(String name, boolean append)130throws FileNotFoundException131{132this(name != null ? new File(name) : null, append);133}134135/**136* Creates a file output stream to write to the file represented by137* the specified <code>File</code> object. A new138* <code>FileDescriptor</code> object is created to represent this139* file connection.140* <p>141* First, if there is a security manager, its <code>checkWrite</code>142* method is called with the path represented by the <code>file</code>143* argument as its argument.144* <p>145* If the file exists but is a directory rather than a regular file, does146* not exist but cannot be created, or cannot be opened for any other147* reason then a <code>FileNotFoundException</code> is thrown.148*149* @param file the file to be opened for writing.150* @exception FileNotFoundException if the file exists but is a directory151* rather than a regular file, does not exist but cannot152* be created, or cannot be opened for any other reason153* @exception SecurityException if a security manager exists and its154* <code>checkWrite</code> method denies write access155* to the file.156* @see java.io.File#getPath()157* @see java.lang.SecurityException158* @see java.lang.SecurityManager#checkWrite(java.lang.String)159*/160public FileOutputStream(File file) throws FileNotFoundException {161this(file, false);162}163164/**165* Creates a file output stream to write to the file represented by166* the specified <code>File</code> object. If the second argument is167* <code>true</code>, then bytes will be written to the end of the file168* rather than the beginning. A new <code>FileDescriptor</code> object is169* created to represent this file connection.170* <p>171* First, if there is a security manager, its <code>checkWrite</code>172* method is called with the path represented by the <code>file</code>173* argument as its argument.174* <p>175* If the file exists but is a directory rather than a regular file, does176* not exist but cannot be created, or cannot be opened for any other177* reason then a <code>FileNotFoundException</code> is thrown.178*179* @param file the file to be opened for writing.180* @param append if <code>true</code>, then bytes will be written181* to the end of the file rather than the beginning182* @exception FileNotFoundException if the file exists but is a directory183* rather than a regular file, does not exist but cannot184* be created, or cannot be opened for any other reason185* @exception SecurityException if a security manager exists and its186* <code>checkWrite</code> method denies write access187* to the file.188* @see java.io.File#getPath()189* @see java.lang.SecurityException190* @see java.lang.SecurityManager#checkWrite(java.lang.String)191* @since 1.4192*/193public FileOutputStream(File file, boolean append)194throws FileNotFoundException195{196String name = (file != null ? file.getPath() : null);197SecurityManager security = System.getSecurityManager();198if (security != null) {199security.checkWrite(name);200}201if (name == null) {202throw new NullPointerException();203}204if (file.isInvalid()) {205throw new FileNotFoundException("Invalid file path");206}207this.fd = new FileDescriptor();208fd.attach(this);209this.append = append;210this.path = name;211212open(name, append);213}214215/**216* Creates a file output stream to write to the specified file217* descriptor, which represents an existing connection to an actual218* file in the file system.219* <p>220* First, if there is a security manager, its <code>checkWrite</code>221* method is called with the file descriptor <code>fdObj</code>222* argument as its argument.223* <p>224* If <code>fdObj</code> is null then a <code>NullPointerException</code>225* is thrown.226* <p>227* This constructor does not throw an exception if <code>fdObj</code>228* is {@link java.io.FileDescriptor#valid() invalid}.229* However, if the methods are invoked on the resulting stream to attempt230* I/O on the stream, an <code>IOException</code> is thrown.231*232* @param fdObj the file descriptor to be opened for writing233* @exception SecurityException if a security manager exists and its234* <code>checkWrite</code> method denies235* write access to the file descriptor236* @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)237*/238public FileOutputStream(FileDescriptor fdObj) {239SecurityManager security = System.getSecurityManager();240if (fdObj == null) {241throw new NullPointerException();242}243if (security != null) {244security.checkWrite(fdObj);245}246this.fd = fdObj;247this.append = false;248this.path = null;249250fd.attach(this);251}252253/**254* Opens a file, with the specified name, for overwriting or appending.255* @param name name of file to be opened256* @param append whether the file is to be opened in append mode257*/258private native void open0(String name, boolean append)259throws FileNotFoundException;260261// wrap native call to allow instrumentation262/**263* Opens a file, with the specified name, for overwriting or appending.264* @param name name of file to be opened265* @param append whether the file is to be opened in append mode266*/267private void open(String name, boolean append)268throws FileNotFoundException {269open0(name, append);270}271272/**273* Writes the specified byte to this file output stream.274*275* @param b the byte to be written.276* @param append {@code true} if the write operation first277* advances the position to the end of file278*/279private native void write(int b, boolean append) throws IOException;280281/**282* Writes the specified byte to this file output stream. Implements283* the <code>write</code> method of <code>OutputStream</code>.284*285* @param b the byte to be written.286* @exception IOException if an I/O error occurs.287*/288public void write(int b) throws IOException {289write(b, append);290}291292/**293* Writes a sub array as a sequence of bytes.294* @param b the data to be written295* @param off the start offset in the data296* @param len the number of bytes that are written297* @param append {@code true} to first advance the position to the298* end of file299* @exception IOException If an I/O error has occurred.300*/301private native void writeBytes(byte b[], int off, int len, boolean append)302throws IOException;303304/**305* Writes <code>b.length</code> bytes from the specified byte array306* to this file output stream.307*308* @param b the data.309* @exception IOException if an I/O error occurs.310*/311public void write(byte b[]) throws IOException {312writeBytes(b, 0, b.length, append);313}314315/**316* Writes <code>len</code> bytes from the specified byte array317* starting at offset <code>off</code> to this file output stream.318*319* @param b the data.320* @param off the start offset in the data.321* @param len the number of bytes to write.322* @exception IOException if an I/O error occurs.323*/324public void write(byte b[], int off, int len) throws IOException {325writeBytes(b, off, len, append);326}327328/**329* Closes this file output stream and releases any system resources330* associated with this stream. This file output stream may no longer331* be used for writing bytes.332*333* <p> If this stream has an associated channel then the channel is closed334* as well.335*336* @exception IOException if an I/O error occurs.337*338* @revised 1.4339* @spec JSR-51340*/341public void close() throws IOException {342synchronized (closeLock) {343if (closed) {344return;345}346closed = true;347}348349if (channel != null) {350channel.close();351}352353fd.closeAll(new Closeable() {354public void close() throws IOException {355close0();356}357});358}359360/**361* Returns the file descriptor associated with this stream.362*363* @return the <code>FileDescriptor</code> object that represents364* the connection to the file in the file system being used365* by this <code>FileOutputStream</code> object.366*367* @exception IOException if an I/O error occurs.368* @see java.io.FileDescriptor369*/370public final FileDescriptor getFD() throws IOException {371if (fd != null) {372return fd;373}374throw new IOException();375}376377/**378* Returns the unique {@link java.nio.channels.FileChannel FileChannel}379* object associated with this file output stream.380*381* <p> The initial {@link java.nio.channels.FileChannel#position()382* position} of the returned channel will be equal to the383* number of bytes written to the file so far unless this stream is in384* append mode, in which case it will be equal to the size of the file.385* Writing bytes to this stream will increment the channel's position386* accordingly. Changing the channel's position, either explicitly or by387* writing, will change this stream's file position.388*389* @return the file channel associated with this file output stream390*391* @since 1.4392* @spec JSR-51393*/394public FileChannel getChannel() {395synchronized (this) {396if (channel == null) {397channel = FileChannelImpl.open(fd, path, false, true, append, this);398}399return channel;400}401}402403/**404* Cleans up the connection to the file, and ensures that the405* <code>close</code> method of this file output stream is406* called when there are no more references to this stream.407*408* @exception IOException if an I/O error occurs.409* @see java.io.FileInputStream#close()410*/411protected void finalize() throws IOException {412if (fd != null) {413if (fd == FileDescriptor.out || fd == FileDescriptor.err) {414flush();415} else {416/* if fd is shared, the references in FileDescriptor417* will ensure that finalizer is only called when418* safe to do so. All references using the fd have419* become unreachable. We can call close()420*/421close();422}423}424}425426private native void close0() throws IOException;427428private static native void initIDs();429430static {431initIDs();432}433434}435436437