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 import sun.misc.IoTrace; 31 import sun.misc.IoTraceContext; 32 33 34 /** 35 * A <code>FileInputStream</code> obtains input bytes 36 * from a file in a file system. What files 37 * are available depends on the host environment. 38 * 39 * <p><code>FileInputStream</code> is meant for reading streams of raw bytes 40 * such as image data. For reading streams of characters, consider using 41 * <code>FileReader</code>. 42 * 43 * @author Arthur van Hoff 44 * @see java.io.File 45 * @see java.io.FileDescriptor 46 * @see java.io.FileOutputStream 47 * @see java.nio.file.Files#newInputStream 48 * @since JDK1.0 49 */ 50 public 51 class FileInputStream extends InputStream 52 { 53 /* File Descriptor - handle to the open file */ 54 private final FileDescriptor fd; 55 56 /* The path of the referenced file (null if the stream is created with a file descriptor) */ 57 private final String path; 58 59 private FileChannel channel = null; 60 61 private final Object closeLock = new Object(); 62 private volatile boolean closed = false; 63 64 /** 65 * Creates a <code>FileInputStream</code> by 66 * opening a connection to an actual file, 67 * the file named by the path name <code>name</code> 68 * in the file system. A new <code>FileDescriptor</code> 69 * object is created to represent this file 70 * connection. 71 * <p> 72 * First, if there is a security 73 * manager, its <code>checkRead</code> method 74 * is called with the <code>name</code> argument 75 * as its argument. 76 * <p> 77 * If the named file does not exist, is a directory rather than a regular 78 * file, or for some other reason cannot be opened for reading then a 79 * <code>FileNotFoundException</code> is thrown. 80 * 81 * @param name the system-dependent file name. 82 * @exception FileNotFoundException if the file does not exist, 83 * is a directory rather than a regular file, 84 * or for some other reason cannot be opened for 85 * reading. 86 * @exception SecurityException if a security manager exists and its 87 * <code>checkRead</code> method denies read access 88 * to the file. 89 * @see java.lang.SecurityManager#checkRead(java.lang.String) 90 */ 91 public FileInputStream(String name) throws FileNotFoundException { 92 this(name != null ? new File(name) : null); 93 } 94 95 /** 96 * Creates a <code>FileInputStream</code> by 97 * opening a connection to an actual file, 98 * the file named by the <code>File</code> 99 * object <code>file</code> in the file system. 100 * A new <code>FileDescriptor</code> object 101 * is created to represent this file connection. 102 * <p> 103 * First, if there is a security manager, 104 * its <code>checkRead</code> method is called 105 * with the path represented by the <code>file</code> 106 * argument as its argument. 107 * <p> 108 * If the named file does not exist, is a directory rather than a regular 109 * file, or for some other reason cannot be opened for reading then a 110 * <code>FileNotFoundException</code> is thrown. 111 * 112 * @param file the file to be opened for reading. 113 * @exception FileNotFoundException if the file does not exist, 114 * is a directory rather than a regular file, 115 * or for some other reason cannot be opened for 116 * reading. 117 * @exception SecurityException if a security manager exists and its 118 * <code>checkRead</code> method denies read access to the file. 119 * @see java.io.File#getPath() 120 * @see java.lang.SecurityManager#checkRead(java.lang.String) 121 */ 122 public FileInputStream(File file) throws FileNotFoundException { 123 String name = (file != null ? file.getPath() : null); 124 SecurityManager security = System.getSecurityManager(); 125 if (security != null) { 126 security.checkRead(name); 127 } 128 if (name == null) { 129 throw new NullPointerException(); 130 } 131 fd = new FileDescriptor(); 132 fd.attach(this); 133 this.path = name; 134 open(name); 135 } 136 137 /** 138 * Creates a <code>FileInputStream</code> by using the file descriptor 139 * <code>fdObj</code>, which represents an existing connection to an 140 * actual file in the file system. 141 * <p> 142 * If there is a security manager, its <code>checkRead</code> method is 143 * called with the file descriptor <code>fdObj</code> as its argument to 144 * see if it's ok to read the file descriptor. If read access is denied 145 * to the file descriptor a <code>SecurityException</code> is thrown. 146 * <p> 147 * If <code>fdObj</code> is null then a <code>NullPointerException</code> 148 * is thrown. 149 * <p> 150 * This constructor does not throw an exception if <code>fdObj</code> 151 * is {@link java.io.FileDescriptor#valid() invalid}. 152 * However, if the methods are invoked on the resulting stream to attempt 153 * I/O on the stream, an <code>IOException</code> is thrown. 154 * 155 * @param fdObj the file descriptor to be opened for reading. 156 * @throws SecurityException if a security manager exists and its 157 * <code>checkRead</code> method denies read access to the 158 * file descriptor. 159 * @see SecurityManager#checkRead(java.io.FileDescriptor) 160 */ 161 public FileInputStream(FileDescriptor fdObj) { 162 SecurityManager security = System.getSecurityManager(); 163 if (fdObj == null) { 164 throw new NullPointerException(); 165 } 166 if (security != null) { 167 security.checkRead(fdObj); 168 } 169 fd = fdObj; 170 path = null; 171 172 /* 173 * FileDescriptor is being shared by streams. 174 * Register this stream with FileDescriptor tracker. 175 */ 176 fd.attach(this); 177 } 178 179 /** 180 * Opens the specified file for reading. 181 * @param name the name of the file 182 */ 183 private native void open(String name) throws FileNotFoundException; 184 185 /** 186 * Reads a byte of data from this input stream. This method blocks 187 * if no input is yet available. 188 * 189 * @return the next byte of data, or <code>-1</code> if the end of the 190 * file is reached. 191 * @exception IOException if an I/O error occurs. 192 */ 193 public int read() throws IOException { 194 IoTraceContext traceContext = IoTrace.fileReadBegin(path); 195 int b = 0; 196 try { 197 b = read0(); 198 } finally { 199 IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1); 200 } 201 return b; 202 } 203 204 private native int read0() throws IOException; 205 206 /** 207 * Reads a subarray as a sequence of bytes. 208 * @param b the data to be written 209 * @param off the start offset in the data 210 * @param len the number of bytes that are written 211 * @exception IOException If an I/O error has occurred. 212 */ 213 private native int readBytes(byte b[], int off, int len) throws IOException; 214 215 /** 216 * Reads up to <code>b.length</code> bytes of data from this input 217 * stream into an array of bytes. This method blocks until some input 218 * is available. 219 * 220 * @param b the buffer into which the data is 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 IOException if an I/O error occurs. 225 */ 226 public int read(byte b[]) throws IOException { 227 IoTraceContext traceContext = IoTrace.fileReadBegin(path); 228 int bytesRead = 0; 229 try { 230 bytesRead = readBytes(b, 0, b.length); 231 } finally { 232 IoTrace.fileReadEnd(traceContext, bytesRead); 233 } 234 return bytesRead; 235 } 236 237 /** 238 * Reads up to <code>len</code> bytes of data from this input stream 239 * into an array of bytes. If <code>len</code> is not zero, the method 240 * blocks until some input is available; otherwise, no 241 * bytes are read and <code>0</code> is returned. 242 * 243 * @param b the buffer into which the data is read. 244 * @param off the start offset in the destination array <code>b</code> 245 * @param len the maximum number of bytes read. 246 * @return the total number of bytes read into the buffer, or 247 * <code>-1</code> if there is no more data because the end of 248 * the file has been reached. 249 * @exception NullPointerException If <code>b</code> is <code>null</code>. 250 * @exception IndexOutOfBoundsException If <code>off</code> is negative, 251 * <code>len</code> is negative, or <code>len</code> is greater than 252 * <code>b.length - off</code> 253 * @exception IOException if an I/O error occurs. 254 */ 255 public int read(byte b[], int off, int len) throws IOException { 256 IoTraceContext traceContext = IoTrace.fileReadBegin(path); 257 int bytesRead = 0; 258 try { 259 bytesRead = readBytes(b, off, len); 260 } finally { 261 IoTrace.fileReadEnd(traceContext, bytesRead); 262 } 263 return bytesRead; 264 } 265 266 /** 267 * Skips over and discards <code>n</code> bytes of data from the 268 * input stream. 269 * 270 * <p>The <code>skip</code> method may, for a variety of 271 * reasons, end up skipping over some smaller number of bytes, 272 * possibly <code>0</code>. If <code>n</code> is negative, an 273 * <code>IOException</code> is thrown, even though the <code>skip</code> 274 * method of the {@link InputStream} superclass does nothing in this case. 275 * The actual number of bytes skipped is returned. 276 * 277 * <p>This method may skip more bytes than are remaining in the backing 278 * file. This produces no exception and the number of bytes skipped 279 * may include some number of bytes that were beyond the EOF of the 280 * backing file. Attempting to read from the stream after skipping past 281 * the end will result in -1 indicating the end of the file. 282 * 283 * @param n the number of bytes to be skipped. 284 * @return the actual number of bytes skipped. 285 * @exception IOException if n is negative, if the stream does not 286 * support seek, or if an I/O error occurs. 287 */ 288 public native long skip(long n) throws IOException; 289 290 /** 291 * Returns an estimate of the number of remaining bytes that can be read (or 292 * skipped over) from this input stream without blocking by the next 293 * invocation of a method for this input stream. The next invocation might be 294 * the same thread or another thread. A single read or skip of this 295 * many bytes will not block, but may read or skip fewer bytes. 296 * 297 * <p> In some cases, a non-blocking read (or skip) may appear to be 298 * blocked when it is merely slow, for example when reading large 299 * files over slow networks. 300 * 301 * @return an estimate of the number of remaining bytes that can be read 302 * (or skipped over) from this input stream without blocking. 303 * @exception IOException if this file input stream has been closed by calling 304 * {@code close} or an I/O error occurs. 305 */ 306 public native int available() throws IOException; 307 308 /** 309 * Closes this file input stream and releases any system resources 310 * associated with the stream. 311 * 312 * <p> If this stream has an associated channel then the channel is closed 313 * as well. 314 * 315 * @exception IOException if an I/O error occurs. 316 * 317 * @revised 1.4 318 * @spec JSR-51 319 */ 320 public void close() throws IOException { 321 synchronized (closeLock) { 322 if (closed) { 323 return; 324 } 325 closed = true; 326 } 327 if (channel != null) { 328 channel.close(); 329 } 330 331 fd.closeAll(new Closeable() { 332 public void close() throws IOException { 333 close0(); 334 } 335 }); 336 } 337 338 /** 339 * Returns the <code>FileDescriptor</code> 340 * object that represents the connection to 341 * the actual file in the file system being 342 * used by this <code>FileInputStream</code>. 343 * 344 * @return the file descriptor object associated with this stream. 345 * @exception IOException if an I/O error occurs. 346 * @see java.io.FileDescriptor 347 */ 348 public final FileDescriptor getFD() throws IOException { 349 if (fd != null) { 350 return fd; 351 } 352 throw new IOException(); 353 } 354 355 /** 356 * Returns the unique {@link java.nio.channels.FileChannel FileChannel} 357 * object associated with this file input stream. 358 * 359 * <p> The initial {@link java.nio.channels.FileChannel#position() 360 * </code>position<code>} of the returned channel will be equal to the 361 * number of bytes read from the file so far. Reading bytes from this 362 * stream will increment the channel's position. Changing the channel's 363 * position, either explicitly or by reading, will change this stream's 364 * file position. 365 * 366 * @return the file channel associated with this file input stream 367 * 368 * @since 1.4 369 * @spec JSR-51 370 */ 371 public FileChannel getChannel() { 372 synchronized (this) { 373 if (channel == null) { 374 channel = FileChannelImpl.open(fd, path, true, false, this); 375 } 376 return channel; 377 } 378 } 379 380 private static native void initIDs(); 381 382 private native void close0() throws IOException; 383 384 static { 385 initIDs(); 386 } 387 388 /** 389 * Ensures that the <code>close</code> method of this file input stream is 390 * called when there are no more references to it. 391 * 392 * @exception IOException if an I/O error occurs. 393 * @see java.io.FileInputStream#close() 394 */ 395 protected void finalize() throws IOException { 396 if ((fd != null) && (fd != FileDescriptor.in)) { 397 /* if fd is shared, the references in FileDescriptor 398 * will ensure that finalizer is only called when 399 * safe to do so. All references using the fd have 400 * become unreachable. We can call close() 401 */ 402 close(); 403 } 404 } 405 }