001/* FileOutputStream.java -- Writes to a file on disk. 002 Copyright (C) 1998, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package java.io; 040 041import gnu.java.nio.FileChannelImpl; 042 043import java.nio.ByteBuffer; 044import java.nio.channels.FileChannel; 045 046/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 047 * "The Java Language Specification", ISBN 0-201-63451-1 048 * Status: Complete to version 1.1. 049 */ 050 051/** 052 * This classes allows a stream of data to be written to a disk file or 053 * any open <code>FileDescriptor</code>. 054 * 055 * @author Aaron M. Renn (arenn@urbanophile.com) 056 * @author Tom Tromey (tromey@cygnus.com) 057 */ 058public class FileOutputStream extends OutputStream 059{ 060 private FileDescriptor fd; 061 062 private final FileChannelImpl ch; 063 064 /** 065 * This method initializes a <code>FileOutputStream</code> object to write 066 * to the named file. The file is created if it does not exist, and 067 * the bytes written are written starting at the beginning of the file if 068 * the <code>append</code> argument is <code>false</code> or at the end 069 * of the file if the <code>append</code> argument is true. 070 * <p> 071 * Before opening a file, a security check is performed by calling the 072 * <code>checkWrite</code> method of the <code>SecurityManager</code> (if 073 * one exists) with the name of the file to be opened. An exception is 074 * thrown if writing is not allowed. 075 * 076 * @param path The name of the file this stream should write to 077 * @param append <code>true</code> to append bytes to the end of the file, 078 * or <code>false</code> to write bytes to the beginning 079 * 080 * @exception SecurityException If write access to the file is not allowed 081 * @exception FileNotFoundException If a non-security error occurs 082 */ 083 public FileOutputStream (String path, boolean append) 084 throws SecurityException, FileNotFoundException 085 { 086 this (new File(path), append); 087 } 088 089 /** 090 * This method initializes a <code>FileOutputStream</code> object to write 091 * to the named file. The file is created if it does not exist, and 092 * the bytes written are written starting at the beginning of the file. 093 * <p> 094 * Before opening a file, a security check is performed by calling the 095 * <code>checkWrite</code> method of the <code>SecurityManager</code> (if 096 * one exists) with the name of the file to be opened. An exception is 097 * thrown if writing is not allowed. 098 * 099 * @param path The name of the file this stream should write to 100 * 101 * @exception SecurityException If write access to the file is not allowed 102 * @exception FileNotFoundException If a non-security error occurs 103 */ 104 public FileOutputStream (String path) 105 throws SecurityException, FileNotFoundException 106 { 107 this (path, false); 108 } 109 110 /** 111 * This method initializes a <code>FileOutputStream</code> object to write 112 * to the specified <code>File</code> object. The file is created if it 113 * does not exist, and the bytes written are written starting at the 114 * beginning of the file. 115 * <p> 116 * Before opening a file, a security check is performed by calling the 117 * <code>checkWrite</code> method of the <code>SecurityManager</code> (if 118 * one exists) with the name of the file to be opened. An exception is 119 * thrown if writing is not allowed. 120 * 121 * @param file The <code>File</code> object this stream should write to 122 * 123 * @exception SecurityException If write access to the file is not allowed 124 * @exception FileNotFoundException If a non-security error occurs 125 */ 126 public FileOutputStream (File file) 127 throws SecurityException, FileNotFoundException 128 { 129 this (file, false); 130 } 131 132 /** 133 * This method initializes a <code>FileOutputStream</code> object to write 134 * to the specified <code>File</code> object. The file is created if it 135 * does not exist, and the bytes written are written starting at the 136 * beginning of the file if the <code>append</code> parameter is 137 * <code>false</code>. Otherwise bytes are written at the end of the 138 * file. 139 * <p> 140 * Before opening a file, a security check is performed by calling the 141 * <code>checkWrite</code> method of the <code>SecurityManager</code> (if 142 * one exists) with the name of the file to be opened. An exception is 143 * thrown if writing is not allowed. 144 * 145 * @param file The <code>File</code> object this stream should write to 146 * @param append <code>true</code> to append bytes to the end of the file, 147 * or <code>false</code> to write bytes to the beginning 148 * 149 * @exception SecurityException If write access to the file is not allowed 150 * @exception FileNotFoundException If a non-security error occurs 151 */ 152 public FileOutputStream (File file, boolean append) 153 throws FileNotFoundException 154 { 155 SecurityManager s = System.getSecurityManager(); 156 if (s != null) 157 s.checkWrite(file.getPath()); 158 159 try 160 { 161 ch = FileChannelImpl.create(file, (append 162 ? FileChannelImpl.WRITE 163 | FileChannelImpl.APPEND 164 : FileChannelImpl.WRITE)); 165 } 166 catch (FileNotFoundException fnfe) 167 { 168 throw fnfe; 169 } 170 catch (IOException ioe) 171 { 172 FileNotFoundException fnfe = new FileNotFoundException(file.getPath()); 173 fnfe.initCause(ioe); 174 throw fnfe; 175 } 176 } 177 178 /** 179 * This method initializes a <code>FileOutputStream</code> object to write 180 * to the file represented by the specified <code>FileDescriptor</code> 181 * object. This method does not create any underlying disk file or 182 * reposition the file pointer of the given descriptor. It assumes that 183 * this descriptor is ready for writing as is. 184 * <p> 185 * Before opening a file, a security check is performed by calling the 186 * <code>checkWrite</code> method of the <code>SecurityManager</code> (if 187 * one exists) with the specified <code>FileDescriptor</code> as an argument. 188 * An exception is thrown if writing is not allowed. 189 * 190 * @param fdObj The <code>FileDescriptor</code> this stream should write to 191 * 192 * @exception SecurityException If write access to the file is not allowed 193 */ 194 public FileOutputStream (FileDescriptor fdObj) 195 throws SecurityException 196 { 197 // Hmm, no other exception but this one to throw, but if the descriptor 198 // isn't valid, we surely don't have "permission" to write to it. 199 if (!fdObj.valid()) 200 throw new SecurityException("Invalid FileDescriptor"); 201 202 SecurityManager s = System.getSecurityManager(); 203 if (s != null) 204 s.checkWrite(fdObj); 205 206 fd = fdObj; 207 ch = (FileChannelImpl) fdObj.channel; 208 } 209 210 FileOutputStream(FileChannelImpl ch) 211 { 212 this.ch = ch; 213 } 214 215 protected void finalize () throws IOException 216 { 217 // We don't actually need this, but we include it because it is 218 // mentioned in the JCL. 219 } 220 221 /** 222 * This method returns a <code>FileDescriptor</code> object representing 223 * the file that is currently being written to 224 * 225 * @return A <code>FileDescriptor</code> object for this stream 226 * 227 * @exception IOException If an error occurs 228 */ 229 public final FileDescriptor getFD () throws IOException 230 { 231 synchronized (this) 232 { 233 if (fd == null) 234 fd = new FileDescriptor (ch); 235 return fd; 236 } 237 } 238 239 /** 240 * This method writes a single byte of data to the file. 241 * 242 * @param b The byte of data to write, passed as an <code>int</code> 243 * 244 * @exception IOException If an error occurs 245 */ 246 public void write (int b) throws IOException 247 { 248 ch.write (b); 249 } 250 251 /** 252 * This method writes all the bytes in the specified array to the 253 * file. 254 * 255 * @param buf The array of bytes to write to the file 256 * 257 * @exception IOException If an error occurs 258 */ 259 public void write (byte[] buf) 260 throws IOException 261 { 262 write (buf, 0, buf.length); 263 } 264 265 /** 266 * This method writes <code>len</code> bytes from the byte array 267 * <code>buf</code> to the file starting at index <code>offset</code>. 268 * 269 * @param buf The array of bytes to write to the file 270 * @param offset The offset into the array to start writing bytes from 271 * @param len The number of bytes to write to the file 272 * 273 * @exception IOException If an error occurs 274 */ 275 public void write (byte[] buf, int offset, int len) 276 throws IOException 277 { 278 if (offset < 0 279 || len < 0 280 || offset + len > buf.length) 281 throw new ArrayIndexOutOfBoundsException (); 282 283 ch.write(ByteBuffer.wrap(buf, offset, len)); 284 } 285 286 /** 287 * This method closes the underlying file. Any further attempts to 288 * write to this stream will likely generate an exception since the 289 * file is closed. 290 * 291 * @exception IOException If an error occurs 292 */ 293 public void close () throws IOException 294 { 295 ch.close(); 296 } 297 298 /** 299 * This method creates a java.nio.channels.FileChannel. 300 * Nio does not allow one to create a file channel directly. 301 * A file channel must be created by first creating an instance of 302 * Input/Output/RandomAccessFile and invoking the getChannel() method on it. 303 */ 304 public synchronized FileChannel getChannel() 305 { 306 return ch; 307 } 308 309} // class FileOutputStream