001: /*
002: * @(#)FileOutputStream.java 1.54 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.io;
029:
030: /**
031: * A file output stream is an output stream for writing data to a
032: * <code>File</code> or to a <code>FileDescriptor</code>. Whether or not
033: * a file is available or may be created depends upon the underlying
034: * platform. Some platforms, in particular, allow a file to be opened
035: * for writing by only one <tt>FileOutputStream</tt> (or other
036: * file-writing object) at a time. In such situations the constructors in
037: * this class will fail if the file involved is already open.
038: *
039: * <p><code>FileOutputStream</code> is meant for writing streams of raw bytes
040: * such as image data. For writing streams of characters, consider using
041: * <code>FileWriter</code>.
042: *
043: * @version 1.39, 02/02/00
044: * @see java.io.File
045: * @see java.io.FileDescriptor
046: * @see java.io.FileInputStream
047: * @since JDK1.0
048: */
049: public class FileOutputStream extends OutputStream {
050: /**
051: * The system dependent file descriptor. The value is
052: * 1 more than actual file descriptor. This means that
053: * the default value 0 indicates that the file is not open.
054: */
055: private FileDescriptor fd;
056:
057: private boolean append = false;
058:
059: /**
060: * Creates an output file stream to write to the file with the
061: * specified name. A new <code>FileDescriptor</code> object is
062: * created to represent this file connection.
063: * <p>
064: * First, if there is a security manager, its <code>checkWrite</code>
065: * method is called with <code>name</code> as its argument.
066: * <p>
067: * If the file exists but is a directory rather than a regular file, does
068: * not exist but cannot be created, or cannot be opened for any other
069: * reason then a <code>FileNotFoundException</code> is thrown.
070: *
071: * @param name the system-dependent filename
072: * @exception FileNotFoundException if the file exists but is a directory
073: * rather than a regular file, does not exist but cannot
074: * be created, or cannot be opened for any other reason
075: * @exception SecurityException if a security manager exists and its
076: * <code>checkWrite</code> method denies write access
077: * to the file.
078: * @see java.lang.SecurityManager#checkWrite(java.lang.String)
079: */
080: public FileOutputStream(String name) throws FileNotFoundException {
081: this (name != null ? new File(name) : null, false);
082: }
083:
084: /**
085: * Creates an output file stream to write to the file with the specified
086: * <code>name</code>. If the second argument is <code>true</code>, then
087: * bytes will be written to the end of the file rather than the beginning.
088: * A new <code>FileDescriptor</code> object is created to represent this
089: * file connection.
090: * <p>
091: * First, if there is a security manager, its <code>checkWrite</code>
092: * method is called with <code>name</code> as its argument.
093: * <p>
094: * If the file exists but is a directory rather than a regular file, does
095: * not exist but cannot be created, or cannot be opened for any other
096: * reason then a <code>FileNotFoundException</code> is thrown.
097: *
098: * @param name the system-dependent file name
099: * @param append if <code>true</code>, then bytes will be written
100: * to the end of the file rather than the beginning
101: * @exception FileNotFoundException if the file exists but is a directory
102: * rather than a regular file, does not exist but cannot
103: * be created, or cannot be opened for any other reason.
104: * @exception SecurityException if a security manager exists and its
105: * <code>checkWrite</code> method denies write access
106: * to the file.
107: * @see java.lang.SecurityManager#checkWrite(java.lang.String)
108: * @since JDK1.1
109: */
110: public FileOutputStream(String name, boolean append)
111: throws FileNotFoundException {
112: this (name != null ? new File(name) : null, append);
113: }
114:
115: /**
116: * Creates a file output stream to write to the file represented by
117: * the specified <code>File</code> object. A new
118: * <code>FileDescriptor</code> object is created to represent this
119: * file connection.
120: * <p>
121: * First, if there is a security manager, its <code>checkWrite</code>
122: * method is called with the path represented by the <code>file</code>
123: * argument as its argument.
124: * <p>
125: * If the file exists but is a directory rather than a regular file, does
126: * not exist but cannot be created, or cannot be opened for any other
127: * reason then a <code>FileNotFoundException</code> is thrown.
128: *
129: * @param file the file to be opened for writing.
130: * @exception FileNotFoundException if the file exists but is a directory
131: * rather than a regular file, does not exist but cannot
132: * be created, or cannot be opened for any other reason
133: * @exception SecurityException if a security manager exists and its
134: * <code>checkWrite</code> method denies write access
135: * to the file.
136: * @see java.io.File#getPath()
137: * @see java.lang.SecurityException
138: * @see java.lang.SecurityManager#checkWrite(java.lang.String)
139: */
140: public FileOutputStream(File file) throws FileNotFoundException {
141: this (file, false);
142: }
143:
144: /**
145: * Creates a file output stream to write to the file represented by
146: * the specified <code>File</code> object. If the second argument is
147: * <code>true</code>, then bytes will be written to the end of the file
148: * rather than the beginning. A new <code>FileDescriptor</code> object is
149: * created to represent this file connection.
150: * <p>
151: * First, if there is a security manager, its <code>checkWrite</code>
152: * method is called with the path represented by the <code>file</code>
153: * argument as its argument.
154: * <p>
155: * If the file exists but is a directory rather than a regular file, does
156: * not exist but cannot be created, or cannot be opened for any other
157: * reason then a <code>FileNotFoundException</code> is thrown.
158: *
159: * @param file the file to be opened for writing.
160: * @param append if <code>true</code>, then bytes will be written
161: * to the end of the file rather than the beginning
162: * @exception FileNotFoundException if the file exists but is a directory
163: * rather than a regular file, does not exist but cannot
164: * be created, or cannot be opened for any other reason
165: * @exception SecurityException if a security manager exists and its
166: * <code>checkWrite</code> method denies write access
167: * to the file.
168: * @see java.io.File#getPath()
169: * @see java.lang.SecurityException
170: * @see java.lang.SecurityManager#checkWrite(java.lang.String)
171: * @since 1.4
172: */
173: public FileOutputStream(File file, boolean append)
174: throws FileNotFoundException {
175: String name = (file != null ? file.getPath() : null);
176: SecurityManager security = System.getSecurityManager();
177: if (security != null) {
178: security.checkWrite(name);
179: }
180: if (name == null) {
181: throw new NullPointerException();
182: }
183: fd = new FileDescriptor();
184: this .append = append;
185: if (append) {
186: openAppend(name);
187: } else {
188: open(name);
189: }
190: }
191:
192: /**
193: * Creates an output file stream to write to the specified file
194: * descriptor, which represents an existing connection to an actual
195: * file in the file system.
196: * <p>
197: * First, if there is a security manager, its <code>checkWrite</code>
198: * method is called with the file descriptor <code>fdObj</code>
199: * argument as its argument.
200: *
201: * @param fdObj the file descriptor to be opened for writing
202: * @exception SecurityException if a security manager exists and its
203: * <code>checkWrite</code> method denies
204: * write access to the file descriptor
205: * @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
206: */
207: public FileOutputStream(FileDescriptor fdObj) {
208: SecurityManager security = System.getSecurityManager();
209: if (fdObj == null) {
210: throw new NullPointerException();
211: }
212: if (security != null) {
213: security.checkWrite(fdObj);
214: }
215: fd = fdObj;
216: }
217:
218: /**
219: * Opens a file, with the specified name, for writing.
220: * @param name name of file to be opened
221: */
222: private native void open(String name) throws FileNotFoundException;
223:
224: /**
225: * Opens a file, with the specified name, for appending.
226: * @param name name of file to be opened
227: */
228: private native void openAppend(String name)
229: throws FileNotFoundException;
230:
231: /**
232: * Writes the specified byte to this file output stream. Implements
233: * the <code>write</code> method of <code>OutputStream</code>.
234: *
235: * @param b the byte to be written.
236: * @exception IOException if an I/O error occurs.
237: */
238: public native void write(int b) throws IOException;
239:
240: /**
241: * Writes a sub array as a sequence of bytes.
242: * @param b the data to be written
243: * @param off the start offset in the data
244: * @param len the number of bytes that are written
245: * @exception IOException If an I/O error has occurred.
246: */
247: private native void writeBytes(byte b[], int off, int len)
248: throws IOException;
249:
250: /**
251: * Writes <code>b.length</code> bytes from the specified byte array
252: * to this file output stream.
253: *
254: * @param b the data.
255: * @exception IOException if an I/O error occurs.
256: */
257: public void write(byte b[]) throws IOException {
258: writeBytes(b, 0, b.length);
259: }
260:
261: /**
262: * Writes <code>len</code> bytes from the specified byte array
263: * starting at offset <code>off</code> to this file output stream.
264: *
265: * @param b the data.
266: * @param off the start offset in the data.
267: * @param len the number of bytes to write.
268: * @exception IOException if an I/O error occurs.
269: */
270: public void write(byte b[], int off, int len) throws IOException {
271: writeBytes(b, off, len);
272: }
273:
274: /**
275: * Closes this file output stream and releases any system resources
276: * associated with this stream. This file output stream may no longer
277: * be used for writing bytes.
278: *
279: * <p> If this stream has an associated channel then the channel is closed
280: * as well.
281: *
282: * @exception IOException if an I/O error occurs.
283: *
284: * @revised 1.4
285: * @spec JSR-51
286: */
287: public void close() throws IOException {
288: close0();
289: }
290:
291: /**
292: * Returns the file descriptor associated with this stream.
293: *
294: * @return the <code>FileDescriptor</code> object that represents
295: * the connection to the file in the file system being used
296: * by this <code>FileOutputStream</code> object.
297: *
298: * @exception IOException if an I/O error occurs.
299: * @see java.io.FileDescriptor
300: */
301: public final FileDescriptor getFD() throws IOException {
302: if (fd != null)
303: return fd;
304: throw new IOException();
305: }
306:
307: /**
308: * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
309: * object associated with this file output stream. </p>
310: *
311: * <p> The initial {@link java.nio.channels.FileChannel#position()
312: * </code>position<code>} of the returned channel will be equal to the
313: * number of bytes written to the file so far unless this stream is in
314: * append mode, in which case it will be equal to the size of the file.
315: * Writing bytes to this stream will increment the channel's position
316: * accordingly. Changing the channel's position, either explicitly or by
317: * writing, will change this stream's file position.
318: *
319: * @return the file channel associated with this file output stream
320: *
321: * @since 1.4
322: * @spec JSR-51
323: */
324: /*
325: public FileChannel getChannel() {
326: synchronized (this) {
327: if (channel == null)
328: channel = FileChannelImpl.open(fd, false, true, this, append);
329: return channel;
330: }
331: }
332: */
333:
334: /**
335: * Cleans up the connection to the file, and ensures that the
336: * <code>close</code> method of this file output stream is
337: * called when there are no more references to this stream.
338: *
339: * @exception IOException if an I/O error occurs.
340: * @see java.io.FileInputStream#close()
341: */
342: protected void finalize() throws IOException {
343: if (fd != null) {
344: if (fd == fd.out || fd == fd.err) {
345: flush();
346: } else {
347: close();
348: }
349: }
350: }
351:
352: private native void close0() throws IOException;
353:
354: private static native void initIDs();
355:
356: static {
357: initIDs();
358: }
359:
360: }
|