9 * by Oracle in the LICENSE file that accompanied this code.
10 *
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 java.util.concurrent.atomic.AtomicBoolean;
30 import jdk.internal.misc.SharedSecrets;
31 import jdk.internal.misc.JavaIOFileDescriptorAccess;
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</code> or to a <code>FileDescriptor</code>. 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</code> is meant for writing streams of raw bytes
45 * such as image data. For writing streams of characters, consider using
46 * <code>FileWriter</code>.
47 *
48 * @author Arthur van Hoff
49 * @see java.io.File
60 */
61 private static final JavaIOFileDescriptorAccess fdAccess =
62 SharedSecrets.getJavaIOFileDescriptorAccess();
63
64 /**
65 * The system dependent file descriptor.
66 */
67 private final FileDescriptor fd;
68
69 /**
70 * The associated channel, initialized lazily.
71 */
72 private volatile FileChannel channel;
73
74 /**
75 * The path of the referenced file
76 * (null if the stream is created with a file descriptor)
77 */
78 private final String path;
79
80 private final AtomicBoolean closed = new AtomicBoolean(false);
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.
324 * @exception IOException if an I/O error occurs.
325 */
326 public void write(byte b[], int off, int len) throws IOException {
327 writeBytes(b, off, len, fdAccess.getAppend(fd));
328 }
329
330 /**
331 * Closes this file output stream and releases any system resources
332 * associated with this stream. This file output stream may no longer
333 * be used for writing bytes.
334 *
335 * <p> If this stream has an associated channel then the channel is closed
336 * as well.
337 *
338 * @exception IOException if an I/O error occurs.
339 *
340 * @revised 1.4
341 * @spec JSR-51
342 */
343 public void close() throws IOException {
344 if (!closed.compareAndSet(false, true)) {
345 // if compareAndSet() returns false closed was already true
346 return;
347 }
348
349 FileChannel fc = channel;
350 if (fc != null) {
351 fc.close();
352 }
353
354 fd.closeAll(new Closeable() {
355 public void close() throws IOException {
356 close0();
357 }
358 });
359 }
360
361 /**
362 * Returns the file descriptor associated with this stream.
363 *
364 * @return the <code>FileDescriptor</code> object that represents
365 * the connection to the file in the file system being used
366 * by this <code>FileOutputStream</code> object.
367 *
382 * <p> The initial {@link java.nio.channels.FileChannel#position()
383 * position} of the returned channel will be equal to the
384 * number of bytes written to the file so far unless this stream is in
385 * append mode, in which case it will be equal to the size of the file.
386 * Writing bytes to this stream will increment the channel's position
387 * accordingly. Changing the channel's position, either explicitly or by
388 * writing, will change this stream's file position.
389 *
390 * @return the file channel associated with this file output stream
391 *
392 * @since 1.4
393 * @spec JSR-51
394 */
395 public FileChannel getChannel() {
396 FileChannel fc = this.channel;
397 if (fc == null) {
398 synchronized (this) {
399 fc = this.channel;
400 if (fc == null) {
401 this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
402 if (closed.get()) {
403 try {
404 fc.close();
405 } catch (IOException ioe) {
406 throw new InternalError(ioe); // should not happen
407 }
408 }
409 }
410 }
411 }
412 return fc;
413 }
414
415 /**
416 * Cleans up the connection to the file, and ensures that the
417 * <code>close</code> method of this file output stream is
418 * called when there are no more references to this stream.
419 *
420 * @exception IOException if an I/O error occurs.
421 * @see java.io.FileInputStream#close()
422 */
|
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
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.misc.SharedSecrets;
30 import jdk.internal.misc.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</code> or to a <code>FileDescriptor</code>. 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</code> is meant for writing streams of raw bytes
44 * such as image data. For writing streams of characters, consider using
45 * <code>FileWriter</code>.
46 *
47 * @author Arthur van Hoff
48 * @see java.io.File
59 */
60 private static final JavaIOFileDescriptorAccess fdAccess =
61 SharedSecrets.getJavaIOFileDescriptorAccess();
62
63 /**
64 * The system dependent file descriptor.
65 */
66 private final FileDescriptor fd;
67
68 /**
69 * The associated channel, initialized lazily.
70 */
71 private volatile FileChannel channel;
72
73 /**
74 * The path of the referenced file
75 * (null if the stream is created with a file descriptor)
76 */
77 private final String path;
78
79 private final Object closeLock = new Object();
80
81 private volatile boolean closed;
82
83 /**
84 * Creates a file output stream to write to the file with the
85 * specified name. A new <code>FileDescriptor</code> object is
86 * created to represent this file connection.
87 * <p>
88 * First, if there is a security manager, its <code>checkWrite</code>
89 * method is called with <code>name</code> as its argument.
90 * <p>
91 * If the file exists but is a directory rather than a regular file, does
92 * not exist but cannot be created, or cannot be opened for any other
93 * reason then a <code>FileNotFoundException</code> is thrown.
94 *
95 * @param name the system-dependent filename
96 * @exception FileNotFoundException if the file exists but is a directory
97 * rather than a regular file, does not exist but cannot
98 * be created, or cannot be opened for any other reason
99 * @exception SecurityException if a security manager exists and its
100 * <code>checkWrite</code> method denies write access
101 * to the file.
325 * @exception IOException if an I/O error occurs.
326 */
327 public void write(byte b[], int off, int len) throws IOException {
328 writeBytes(b, off, len, fdAccess.getAppend(fd));
329 }
330
331 /**
332 * Closes this file output stream and releases any system resources
333 * associated with this stream. This file output stream may no longer
334 * be used for writing bytes.
335 *
336 * <p> If this stream has an associated channel then the channel is closed
337 * as well.
338 *
339 * @exception IOException if an I/O error occurs.
340 *
341 * @revised 1.4
342 * @spec JSR-51
343 */
344 public void close() throws IOException {
345 if (closed) {
346 return;
347 }
348 synchronized (closeLock) {
349 if (closed) {
350 return;
351 }
352 closed = true;
353 }
354
355 FileChannel fc = channel;
356 if (fc != null) {
357 fc.close();
358 }
359
360 fd.closeAll(new Closeable() {
361 public void close() throws IOException {
362 close0();
363 }
364 });
365 }
366
367 /**
368 * Returns the file descriptor associated with this stream.
369 *
370 * @return the <code>FileDescriptor</code> object that represents
371 * the connection to the file in the file system being used
372 * by this <code>FileOutputStream</code> object.
373 *
388 * <p> The initial {@link java.nio.channels.FileChannel#position()
389 * position} of the returned channel will be equal to the
390 * number of bytes written to the file so far unless this stream is in
391 * append mode, in which case it will be equal to the size of the file.
392 * Writing bytes to this stream will increment the channel's position
393 * accordingly. Changing the channel's position, either explicitly or by
394 * writing, will change this stream's file position.
395 *
396 * @return the file channel associated with this file output stream
397 *
398 * @since 1.4
399 * @spec JSR-51
400 */
401 public FileChannel getChannel() {
402 FileChannel fc = this.channel;
403 if (fc == null) {
404 synchronized (this) {
405 fc = this.channel;
406 if (fc == null) {
407 this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
408 if (closed) {
409 try {
410 fc.close();
411 } catch (IOException ioe) {
412 throw new InternalError(ioe); // should not happen
413 }
414 }
415 }
416 }
417 }
418 return fc;
419 }
420
421 /**
422 * Cleans up the connection to the file, and ensures that the
423 * <code>close</code> method of this file output stream is
424 * called when there are no more references to this stream.
425 *
426 * @exception IOException if an I/O error occurs.
427 * @see java.io.FileInputStream#close()
428 */
|