1 /* 2 * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.io; 27 28 import java.nio.channels.FileChannel; 29 import sun.nio.ch.FileChannelImpl; 30 31 32 /** 33 * A <code>FileInputStream</code> obtains input bytes 34 * from a file in a file system. What files 35 * are available depends on the host environment. 36 * 37 * <p><code>FileInputStream</code> is meant for reading streams of raw bytes 38 * such as image data. For reading streams of characters, consider using 39 * <code>FileReader</code>. 40 * 41 * @author Arthur van Hoff 42 * @see java.io.File 43 * @see java.io.FileDescriptor 44 * @see java.io.FileOutputStream 45 * @see java.nio.file.Files#newInputStream 46 * @since JDK1.0 47 */ 48 public 49 class FileInputStream extends InputStream 50 { 51 /* File Descriptor - handle to the open file */ 52 private final FileDescriptor fd; 53 54 private FileChannel channel = null; 55 56 private final Object closeLock = new Object(); 57 private volatile boolean closed = false; 58 59 /** 60 * Creates a <code>FileInputStream</code> by 61 * opening a connection to an actual file, 62 * the file named by the path name <code>name</code> 63 * in the file system. A new <code>FileDescriptor</code> 64 * object is created to represent this file 65 * connection. 66 * <p> 67 * First, if there is a security 68 * manager, its <code>checkRead</code> method 69 * is called with the <code>name</code> argument 70 * as its argument. 71 * <p> 72 * If the named file does not exist, is a directory rather than a regular 73 * file, or for some other reason cannot be opened for reading then a 74 * <code>FileNotFoundException</code> is thrown. 75 * 76 * @param name the system-dependent file name. 77 * @exception FileNotFoundException if the file does not exist, 78 * is a directory rather than a regular file, 79 * or for some other reason cannot be opened for 80 * reading. 81 * @exception SecurityException if a security manager exists and its 82 * <code>checkRead</code> method denies read access 83 * to the file. 84 * @see java.lang.SecurityManager#checkRead(java.lang.String) 85 */ 86 public FileInputStream(String name) throws FileNotFoundException { 87 this(name != null ? new File(name) : null); 88 } 89 90 /** 91 * Creates a <code>FileInputStream</code> by 92 * opening a connection to an actual file, 93 * the file named by the <code>File</code> 94 * object <code>file</code> in the file system. 95 * A new <code>FileDescriptor</code> object 96 * is created to represent this file connection. 97 * <p> 98 * First, if there is a security manager, 99 * its <code>checkRead</code> method is called 100 * with the path represented by the <code>file</code> 101 * argument as its argument. 102 * <p> 103 * If the named file does not exist, is a directory rather than a regular 104 * file, or for some other reason cannot be opened for reading then a 105 * <code>FileNotFoundException</code> is thrown. 106 * 107 * @param file the file to be opened for reading. 108 * @exception FileNotFoundException if the file does not exist, 109 * is a directory rather than a regular file, 110 * or for some other reason cannot be opened for 111 * reading. 112 * @exception SecurityException if a security manager exists and its 113 * <code>checkRead</code> method denies read access to the file. 114 * @see java.io.File#getPath() 115 * @see java.lang.SecurityManager#checkRead(java.lang.String) 116 */ 117 public FileInputStream(File file) throws FileNotFoundException { 118 String name = (file != null ? file.getPath() : null); 119 SecurityManager security = System.getSecurityManager(); 120 if (security != null) { 121 security.checkRead(name); 122 } 123 if (name == null) { 124 throw new NullPointerException(); 125 } 126 fd = new FileDescriptor(); 127 fd.attach(this); 128 open(name); 129 } 130 131 /** 132 * Creates a <code>FileInputStream</code> by using the file descriptor 133 * <code>fdObj</code>, which represents an existing connection to an 134 * actual file in the file system. 135 * <p> 136 * If there is a security manager, its <code>checkRead</code> method is 137 * called with the file descriptor <code>fdObj</code> as its argument to 138 * see if it's ok to read the file descriptor. If read access is denied 139 * to the file descriptor a <code>SecurityException</code> is thrown. 140 * <p> 141 * If <code>fdObj</code> is null then a <code>NullPointerException</code> 142 * is thrown. 143 * <p> 144 * This constructor does not throw an exception if <code>fdObj</code> 145 * is {@link java.io.FileDescriptor#valid() invalid}. 146 * However, if the methods are invoked on the resulting stream to attempt 147 * I/O on the stream, an <code>IOException</code> is thrown. 148 * 149 * @param fdObj the file descriptor to be opened for reading. 150 * @throws SecurityException if a security manager exists and its 151 * <code>checkRead</code> method denies read access to the 152 * file descriptor. 153 * @see SecurityManager#checkRead(java.io.FileDescriptor) 154 */ 155 public FileInputStream(FileDescriptor fdObj) { 156 SecurityManager security = System.getSecurityManager(); 157 if (fdObj == null) { 158 throw new NullPointerException(); 159 } 160 if (security != null) { 161 security.checkRead(fdObj); 162 } 163 fd = fdObj; 164 165 /* 166 * FileDescriptor is being shared by streams. 167 * Register this stream with FileDescriptor tracker. 168 */ 169 fd.attach(this); 170 } 171 172 /** 173 * Opens the specified file for reading. 174 * @param name the name of the file 175 */ 176 private native void open(String name) throws FileNotFoundException; 177 178 /** 179 * Reads a byte of data from this input stream. This method blocks 180 * if no input is yet available. 181 * 182 * @return the next byte of data, or <code>-1</code> if the end of the 183 * file is reached. 184 * @exception IOException if an I/O error occurs. 185 */ 186 public native int read() throws IOException; 187 188 /** 189 * Reads a subarray as a sequence of bytes. 190 * @param b the data to be written 191 * @param off the start offset in the data 192 * @param len the number of bytes that are written 193 * @exception IOException If an I/O error has occurred. 194 */ 195 private native int readBytes(byte b[], int off, int len) throws IOException; 196 197 /** 198 * Reads up to <code>b.length</code> bytes of data from this input 199 * stream into an array of bytes. This method blocks until some input 200 * is available. 201 * 202 * @param b the buffer into which the data is read. 203 * @return the total number of bytes read into the buffer, or 204 * <code>-1</code> if there is no more data because the end of 205 * the file has been reached. 206 * @exception IOException if an I/O error occurs. 207 */ 208 public int read(byte b[]) throws IOException { 209 return readBytes(b, 0, b.length); 210 } 211 212 /** 213 * Reads up to <code>len</code> bytes of data from this input stream 214 * into an array of bytes. If <code>len</code> is not zero, the method 215 * blocks until some input is available; otherwise, no 216 * bytes are read and <code>0</code> is returned. 217 * 218 * @param b the buffer into which the data is read. 219 * @param off the start offset in the destination array <code>b</code> 220 * @param len the maximum number of bytes read. 221 * @return the total number of bytes read into the buffer, or 222 * <code>-1</code> if there is no more data because the end of 223 * the file has been reached. 224 * @exception NullPointerException If <code>b</code> is <code>null</code>. 225 * @exception IndexOutOfBoundsException If <code>off</code> is negative, 226 * <code>len</code> is negative, or <code>len</code> is greater than 227 * <code>b.length - off</code> 228 * @exception IOException if an I/O error occurs. 229 */ 230 public int read(byte b[], int off, int len) throws IOException { 231 return readBytes(b, off, len); 232 } 233 234 /** 235 * Skips over and discards <code>n</code> bytes of data from the 236 * input stream. 237 * 238 * <p>The <code>skip</code> method may, for a variety of 239 * reasons, end up skipping over some smaller number of bytes, 240 * possibly <code>0</code>. If <code>n</code> is negative, an 241 * <code>IOException</code> is thrown, even though the <code>skip</code> 242 * method of the {@link InputStream} superclass does nothing in this case. 243 * The actual number of bytes skipped is returned. 244 * 245 * <p>This method may skip more bytes than are remaining in the backing 246 * file. This produces no exception and the number of bytes skipped 247 * may include some number of bytes that were beyond the EOF of the 248 * backing file. Attempting to read from the stream after skipping past 249 * the end will result in -1 indicating the end of the file. 250 * 251 * @param n the number of bytes to be skipped. 252 * @return the actual number of bytes skipped. 253 * @exception IOException if n is negative, if the stream does not 254 * support seek, or if an I/O error occurs. 255 */ 256 public native long skip(long n) throws IOException; 257 258 /** 259 * Returns an estimate of the number of remaining bytes that can be read (or 260 * skipped over) from this input stream without blocking by the next 261 * invocation of a method for this input stream. The next invocation might be 262 * the same thread or another thread. A single read or skip of this 263 * many bytes will not block, but may read or skip fewer bytes. 264 * 265 * <p> In some cases, a non-blocking read (or skip) may appear to be 266 * blocked when it is merely slow, for example when reading large 267 * files over slow networks. 268 * 269 * @return an estimate of the number of remaining bytes that can be read 270 * (or skipped over) from this input stream without blocking. 271 * @exception IOException if this file input stream has been closed by calling 272 * {@code close} or an I/O error occurs. 273 */ 274 public native int available() throws IOException; 275 276 /** 277 * Closes this file input stream and releases any system resources 278 * associated with the stream. 279 * 280 * <p> If this stream has an associated channel then the channel is closed 281 * as well. 282 * 283 * @exception IOException if an I/O error occurs. 284 * 285 * @revised 1.4 286 * @spec JSR-51 287 */ 288 public void close() throws IOException { 289 synchronized (closeLock) { 290 if (closed) { 291 return; 292 } 293 closed = true; 294 } 295 if (channel != null) { 296 channel.close(); 297 } 298 299 fd.closeAll(new Closeable() { 300 public void close() throws IOException { 301 close0(); 302 } 303 }); 304 } 305 306 /** 307 * Returns the <code>FileDescriptor</code> 308 * object that represents the connection to 309 * the actual file in the file system being 310 * used by this <code>FileInputStream</code>. 311 * 312 * @return the file descriptor object associated with this stream. 313 * @exception IOException if an I/O error occurs. 314 * @see java.io.FileDescriptor 315 */ 316 public final FileDescriptor getFD() throws IOException { 317 if (fd != null) { 318 return fd; 319 } 320 throw new IOException(); 321 } 322 323 /** 324 * Returns the unique {@link java.nio.channels.FileChannel FileChannel} 325 * object associated with this file input stream. 326 * 327 * <p> The initial {@link java.nio.channels.FileChannel#position() 328 * </code>position<code>} of the returned channel will be equal to the 329 * number of bytes read from the file so far. Reading bytes from this 330 * stream will increment the channel's position. Changing the channel's 331 * position, either explicitly or by reading, will change this stream's 332 * file position. 333 * 334 * @return the file channel associated with this file input stream 335 * 336 * @since 1.4 337 * @spec JSR-51 338 */ 339 public FileChannel getChannel() { 340 synchronized (this) { 341 if (channel == null) { 342 channel = FileChannelImpl.open(fd, true, false, this); 343 } 344 return channel; 345 } 346 } 347 348 private static native void initIDs(); 349 350 private native void close0() throws IOException; 351 352 static { 353 initIDs(); 354 } 355 356 /** 357 * Ensures that the <code>close</code> method of this file input stream is 358 * called when there are no more references to it. 359 * 360 * @exception IOException if an I/O error occurs. 361 * @see java.io.FileInputStream#close() 362 */ 363 protected void finalize() throws IOException { 364 if ((fd != null) && (fd != FileDescriptor.in)) { 365 /* if fd is shared, the references in FileDescriptor 366 * will ensure that finalizer is only called when 367 * safe to do so. All references using the fd have 368 * become unreachable. We can call close() 369 */ 370 close(); 371 } 372 } 373 }