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