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
185 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
186 * @since 1.4
187 */
188 public FileOutputStream(File file, boolean append)
189 throws FileNotFoundException
190 {
191 String name = (file != null ? file.getPath() : null);
192 SecurityManager security = System.getSecurityManager();
193 if (security != null) {
194 security.checkWrite(name);
195 }
196 if (name == null) {
197 throw new NullPointerException();
198 }
199 if (file.isInvalid()) {
200 throw new FileNotFoundException("Invalid file path");
201 }
202 this.fd = new FileDescriptor();
203 fd.attach(this);
204 this.append = append;
205
206 open(name, append);
207 }
208
209 /**
210 * Creates a file output stream to write to the specified file
211 * descriptor, which represents an existing connection to an actual
212 * file in the file system.
213 * <p>
214 * First, if there is a security manager, its <code>checkWrite</code>
215 * method is called with the file descriptor <code>fdObj</code>
216 * argument as its argument.
217 * <p>
218 * If <code>fdObj</code> is null then a <code>NullPointerException</code>
219 * is thrown.
220 * <p>
221 * This constructor does not throw an exception if <code>fdObj</code>
222 * is {@link java.io.FileDescriptor#valid() invalid}.
223 * However, if the methods are invoked on the resulting stream to attempt
224 * I/O on the stream, an <code>IOException</code> is thrown.
225 *
226 * @param fdObj the file descriptor to be opened for writing
227 * @exception SecurityException if a security manager exists and its
228 * <code>checkWrite</code> method denies
229 * write access to the file descriptor
230 * @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
231 */
232 public FileOutputStream(FileDescriptor fdObj) {
233 SecurityManager security = System.getSecurityManager();
234 if (fdObj == null) {
235 throw new NullPointerException();
236 }
237 if (security != null) {
238 security.checkWrite(fdObj);
239 }
240 this.fd = fdObj;
241 this.append = false;
242
243 fd.attach(this);
244 }
245
246 /**
247 * Opens a file, with the specified name, for overwriting or appending.
248 * @param name name of file to be opened
249 * @param append whether the file is to be opened in append mode
250 */
251 private native void open(String name, boolean append)
252 throws FileNotFoundException;
253
254 /**
255 * Writes the specified byte to this file output stream.
256 *
257 * @param b the byte to be written.
258 * @param append {@code true} if the write operation first
259 * advances the position to the end of file
260 */
261 private native void write(int b, boolean append) throws IOException;
359 /**
360 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
361 * object associated with this file output stream.
362 *
363 * <p> The initial {@link java.nio.channels.FileChannel#position()
364 * position} of the returned channel will be equal to the
365 * number of bytes written to the file so far unless this stream is in
366 * append mode, in which case it will be equal to the size of the file.
367 * Writing bytes to this stream will increment the channel's position
368 * accordingly. Changing the channel's position, either explicitly or by
369 * writing, will change this stream's file position.
370 *
371 * @return the file channel associated with this file output stream
372 *
373 * @since 1.4
374 * @spec JSR-51
375 */
376 public FileChannel getChannel() {
377 synchronized (this) {
378 if (channel == null) {
379 channel = FileChannelImpl.open(fd, false, true, append, this);
380 }
381 return channel;
382 }
383 }
384
385 /**
386 * Cleans up the connection to the file, and ensures that the
387 * <code>close</code> method of this file output stream is
388 * called when there are no more references to this stream.
389 *
390 * @exception IOException if an I/O error occurs.
391 * @see java.io.FileInputStream#close()
392 */
393 protected void finalize() throws IOException {
394 if (fd != null) {
395 if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
396 flush();
397 } else {
398 /* if fd is shared, the references in FileDescriptor
399 * will ensure that finalizer is only called when
|
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 /**
71 * The path of the referenced file (null if the stream is created with a file descriptor)
72 */
73 private final String path;
74
75 private final Object closeLock = new Object();
76 private volatile boolean closed = false;
77
78 /**
79 * Creates a file output stream to write to the file with the
80 * specified name. A new <code>FileDescriptor</code> object is
81 * 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, does
87 * not exist but cannot be created, or cannot be opened for any other
88 * reason then a <code>FileNotFoundException</code> is thrown.
89 *
90 * @param name the system-dependent filename
91 * @exception FileNotFoundException if the file exists but is a directory
92 * rather than a regular file, does not exist but cannot
93 * be created, or cannot be opened for any other reason
94 * @exception SecurityException if a security manager exists and its
190 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
191 * @since 1.4
192 */
193 public FileOutputStream(File file, boolean append)
194 throws FileNotFoundException
195 {
196 String name = (file != null ? file.getPath() : null);
197 SecurityManager security = System.getSecurityManager();
198 if (security != null) {
199 security.checkWrite(name);
200 }
201 if (name == null) {
202 throw new NullPointerException();
203 }
204 if (file.isInvalid()) {
205 throw new FileNotFoundException("Invalid file path");
206 }
207 this.fd = new FileDescriptor();
208 fd.attach(this);
209 this.append = append;
210 this.path = name;
211
212 open(name, append);
213 }
214
215 /**
216 * Creates a file output stream to write to the specified file
217 * descriptor, which represents an existing connection to an actual
218 * 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 attempt
230 * I/O on the stream, an <code>IOException</code> is thrown.
231 *
232 * @param fdObj the file descriptor to be opened for writing
233 * @exception SecurityException if a security manager exists and its
234 * <code>checkWrite</code> method denies
235 * write access to the file descriptor
236 * @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
237 */
238 public FileOutputStream(FileDescriptor fdObj) {
239 SecurityManager security = System.getSecurityManager();
240 if (fdObj == null) {
241 throw new NullPointerException();
242 }
243 if (security != null) {
244 security.checkWrite(fdObj);
245 }
246 this.fd = fdObj;
247 this.append = false;
248 this.path = null;
249
250 fd.attach(this);
251 }
252
253 /**
254 * Opens a file, with the specified name, for overwriting or appending.
255 * @param name name of file to be opened
256 * @param append whether the file is to be opened in append mode
257 */
258 private native void open(String name, boolean append)
259 throws FileNotFoundException;
260
261 /**
262 * Writes the specified byte to this file output stream.
263 *
264 * @param b the byte to be written.
265 * @param append {@code true} if the write operation first
266 * advances the position to the end of file
267 */
268 private native void write(int b, boolean append) throws IOException;
366 /**
367 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
368 * object associated with this file output stream.
369 *
370 * <p> The initial {@link java.nio.channels.FileChannel#position()
371 * position} of the returned channel will be equal to the
372 * number of bytes written to the file so far unless this stream is in
373 * append mode, in which case it will be equal to the size of the file.
374 * Writing bytes to this stream will increment the channel's position
375 * accordingly. Changing the channel's position, either explicitly or by
376 * writing, will change this stream's file position.
377 *
378 * @return the file channel associated with this file output stream
379 *
380 * @since 1.4
381 * @spec JSR-51
382 */
383 public FileChannel getChannel() {
384 synchronized (this) {
385 if (channel == null) {
386 channel = FileChannelImpl.open(fd, path, false, true, append, this);
387 }
388 return channel;
389 }
390 }
391
392 /**
393 * Cleans up the connection to the file, and ensures that the
394 * <code>close</code> method of this file output stream is
395 * called when there are no more references to this stream.
396 *
397 * @exception IOException if an I/O error occurs.
398 * @see java.io.FileInputStream#close()
399 */
400 protected void finalize() throws IOException {
401 if (fd != null) {
402 if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
403 flush();
404 } else {
405 /* if fd is shared, the references in FileDescriptor
406 * will ensure that finalizer is only called when
|