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