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