001/* FileInputStream.java -- An input stream that reads from disk files. 002 Copyright (C) 1998, 2002, 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 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. 049 * Status: Believed complete and correct. 050 */ 051 052/** 053 * This class is a stream that reads its bytes from a file. 054 * 055 * @author Aaron M. Renn (arenn@urbanophile.com) 056 * @author Warren Levy (warrenl@cygnus.com) 057 */ 058public class FileInputStream extends InputStream 059{ 060 /** 061 * This is the native file handle for the file this stream is reading from 062 */ 063 private FileDescriptor fd; 064 065 private FileChannelImpl ch; 066 067 /** 068 * This method initializes a <code>FileInputStream</code> to read from the 069 * specified named file. A security check is first made to determine 070 * whether or not access to this file is allowed. This is done by 071 * calling the <code>checkRead()</code> method of the 072 * <code>SecurityManager</code> 073 * (if one exists) with the name of this file. An exception is thrown 074 * if reading is not allowed. If the file does not exist, an exception 075 * is also thrown. 076 * 077 * @param name The name of the file this stream should read from 078 * 079 * @exception SecurityException If read access to the file is not allowed 080 * @exception FileNotFoundException If the file does not exist 081 * or if it is a directory 082 */ 083 public FileInputStream(String name) throws FileNotFoundException 084 { 085 this(new File(name)); 086 } 087 088 /** 089 * This method initializes a <code>FileInputStream</code> to read from the 090 * specified <code>File</code> object. A security check is first 091 * made to determine 092 * whether or not access to this file is allowed. This is done by 093 * calling the <code>checkRead()</code> method of the 094 * <code>SecurityManager</code> 095 * (if one exists) with the name of this file. An exception is thrown 096 * if reading is not allowed. If the file does not exist, an exception 097 * is also thrown. 098 * 099 * @param file The <code>File</code> object this stream should read from 100 * 101 * @exception SecurityException If read access to the file is not allowed 102 * @exception FileNotFoundException If the file does not exist 103 * or if it is a directory. 104 */ 105 public FileInputStream(File file) throws FileNotFoundException 106 { 107 SecurityManager s = System.getSecurityManager(); 108 if (s != null) 109 s.checkRead(file.getPath()); 110 111 try 112 { 113 ch = FileChannelImpl.create(file, FileChannelImpl.READ); 114 } 115 catch (FileNotFoundException fnfe) 116 { 117 throw fnfe; 118 } 119 catch (IOException ioe) 120 { 121 FileNotFoundException fnfe = new FileNotFoundException(file.getPath()); 122 fnfe.initCause(ioe); 123 throw fnfe; 124 } 125 } 126 127 /** 128 * This method initializes a <code>FileInputStream</code> to read from the 129 * specified <code>FileDescriptor</code> object. A security 130 * check is first made to 131 * determine whether or not access to this file is allowed. This is done by 132 * calling the <code>checkRead()</code> method of the 133 * <code>SecurityManager</code> 134 * (if one exists) with the specified <code>FileDescriptor</code> 135 * An exception is 136 * thrown if reading is not allowed. 137 * 138 * @param fdObj The <code>FileDescriptor</code> object this stream 139 * should read from 140 * 141 * @exception SecurityException If read access to the file is not allowed 142 */ 143 public FileInputStream(FileDescriptor fdObj) 144 { 145 SecurityManager s = System.getSecurityManager(); 146 if (s != null) 147 s.checkRead(fdObj); 148 149 fd = fdObj; 150 ch = (FileChannelImpl) fdObj.channel; 151 } 152 153 FileInputStream(FileChannelImpl ch) 154 { 155 this.ch = ch; 156 } 157 158 /** 159 * This method returns the number of bytes that can be read from this 160 * stream before a read can block. A return of 0 indicates that blocking 161 * might (or might not) occur on the very next read attempt. 162 * <p> 163 * This method returns the number of unread bytes remaining in the file if 164 * the descriptor being read from is an actual file. If this method is 165 * reading from a ''special'' file such a the standard input, this method 166 * will return the appropriate value for the stream being read. 167 * <p> 168 * Be aware that reads on plain files that do not reside locally might 169 * possibly block even if this method says they should not. For example, 170 * a remote server might crash, preventing an NFS mounted file from being 171 * read. 172 * 173 * @return The number of bytes that can be read before blocking could occur 174 * 175 * @exception IOException If an error occurs 176 */ 177 public int available() throws IOException 178 { 179 return ch.available(); 180 } 181 182 /** 183 * This method closes the stream. Any futher attempts to read from the 184 * stream will likely generate an IOException since the underlying file 185 * will be closed. 186 * 187 * @exception IOException If an error occurs. 188 */ 189 public void close() throws IOException 190 { 191 ch.close(); 192 } 193 194 protected void finalize() throws IOException 195 { 196 // We don't actually need this, but we include it because it is 197 // mentioned in the JCL. 198 } 199 200 /** 201 * This method returns a <code>FileDescriptor</code> object representing the 202 * underlying native file handle of the file this stream is reading 203 * from 204 * 205 * @return A <code>FileDescriptor</code> for this stream 206 * 207 * @exception IOException If an error occurs 208 */ 209 public final FileDescriptor getFD() throws IOException 210 { 211 synchronized (this) 212 { 213 if (fd == null) 214 fd = new FileDescriptor (ch); 215 return fd; 216 } 217 } 218 219 /** 220 * This method reads an unsigned byte from the input stream and returns it 221 * as an int in the range of 0-255. This method also will return -1 if 222 * the end of the stream has been reached. 223 * <p> 224 * This method will block until the byte can be read. 225 * 226 * @return The byte read or -1 if end of stream 227 * 228 * @exception IOException If an error occurs 229 */ 230 public int read() throws IOException 231 { 232 return ch.read(); 233 } 234 235 /** 236 * This method reads bytes from a stream and stores them into a caller 237 * supplied buffer. This method attempts to completely fill the buffer, 238 * but can return before doing so. The actual number of bytes read is 239 * returned as an int. A -1 is returned to indicate the end of the stream. 240 * <p> 241 * This method will block until some data can be read. 242 * <p> 243 * This method operates by calling an overloaded read method like so: 244 * <code>read(buf, 0, buf.length)</code> 245 * 246 * @param buf The buffer into which the bytes read will be stored. 247 * 248 * @return The number of bytes read or -1 if end of stream. 249 * 250 * @exception IOException If an error occurs. 251 */ 252 public int read(byte[] buf) throws IOException 253 { 254 return read(buf, 0, buf.length); 255 } 256 257 /** 258 * This method read bytes from a stream and stores them into a caller 259 * supplied buffer. It starts storing the data at index 260 * <code>offset</code> into 261 * the buffer and attempts to read <code>len</code> bytes. This method can 262 * return before reading the number of bytes requested. The actual number 263 * of bytes read is returned as an int. A -1 is returned to indicate the 264 * end of the stream. 265 * <p> 266 * This method will block until some data can be read. 267 * 268 * @param buf The array into which the bytes read should be stored 269 * @param offset The offset into the array to start storing bytes 270 * @param len The requested number of bytes to read 271 * 272 * @return The actual number of bytes read, or -1 if end of stream. 273 * 274 * @exception IOException If an error occurs. 275 */ 276 public int read(byte[] buf, int offset, int len) throws IOException 277 { 278 if (offset < 0 279 || len < 0 280 || offset + len > buf.length) 281 throw new ArrayIndexOutOfBoundsException(); 282 283 return ch.read(ByteBuffer.wrap(buf, offset, len)); 284 } 285 286 /** 287 * This method skips the specified number of bytes in the stream. It 288 * returns the actual number of bytes skipped, which may be less than the 289 * requested amount. 290 * <p> 291 * @param numBytes The requested number of bytes to skip 292 * 293 * @return The actual number of bytes skipped. 294 * 295 * @exception IOException If an error occurs 296 */ 297 public synchronized long skip (long numBytes) throws IOException 298 { 299 if (numBytes < 0) 300 throw new IllegalArgumentException ("Can't skip negative bytes: " + 301 numBytes); 302 303 if (numBytes == 0) 304 return 0; 305 306 long oldPos = ch.position (); 307 ch.position(oldPos + numBytes); 308 return ch.position() - oldPos; 309 } 310 311 /** 312 * This method creates a java.nio.channels.FileChannel. 313 * Nio does not allow one to create a file channel directly. 314 * A file channel must be created by first creating an instance of 315 * Input/Output/RandomAccessFile and invoking the getChannel() method on it. 316 */ 317 public synchronized FileChannel getChannel () 318 { 319 return ch; 320 } 321 322} // class FileInputStream