1/* 2 * Copyright (c) 1994, 2017, 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 26package java.io; 27 28import java.nio.channels.FileChannel; 29import 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 1.0 47 */ 48public 49class FileInputStream extends InputStream 50{ 51 /* File Descriptor - handle to the open file */ 52 private final FileDescriptor fd; 53 54 /** 55 * The path of the referenced file 56 * (null if the stream is created with a file descriptor) 57 */ 58 private final String path; 59 60 private volatile FileChannel channel; 61 62 private final Object closeLock = new Object(); 63 64 private volatile boolean closed; 65 66 /** 67 * Creates a <code>FileInputStream</code> by 68 * opening a connection to an actual file, 69 * the file named by the path name <code>name</code> 70 * in the file system. A new <code>FileDescriptor</code> 71 * object is created to represent this file 72 * connection. 73 * <p> 74 * First, if there is a security 75 * manager, its <code>checkRead</code> method 76 * is called with the <code>name</code> argument 77 * as its argument. 78 * <p> 79 * If the named file does not exist, is a directory rather than a regular 80 * file, or for some other reason cannot be opened for reading then a 81 * <code>FileNotFoundException</code> is thrown. 82 * 83 * @param name the system-dependent file name. 84 * @exception FileNotFoundException if the file does not exist, 85 * is a directory rather than a regular file, 86 * or for some other reason cannot be opened for 87 * reading. 88 * @exception SecurityException if a security manager exists and its 89 * <code>checkRead</code> method denies read access 90 * to the file. 91 * @see java.lang.SecurityManager#checkRead(java.lang.String) 92 */ 93 public FileInputStream(String name) throws FileNotFoundException { 94 this(name != null ? new File(name) : null); 95 } 96 97 /** 98 * Creates a <code>FileInputStream</code> by 99 * opening a connection to an actual file, 100 * the file named by the <code>File</code> 101 * object <code>file</code> in the file system. 102 * A new <code>FileDescriptor</code> object 103 * is created to represent this file connection. 104 * <p> 105 * First, if there is a security manager, 106 * its <code>checkRead</code> method is called 107 * with the path represented by the <code>file</code> 108 * argument as its argument. 109 * <p> 110 * If the named file does not exist, is a directory rather than a regular 111 * file, or for some other reason cannot be opened for reading then a 112 * <code>FileNotFoundException</code> is thrown. 113 * 114 * @param file the file to be opened for reading. 115 * @exception FileNotFoundException if the file does not exist, 116 * is a directory rather than a regular file, 117 * or for some other reason cannot be opened for 118 * reading. 119 * @exception SecurityException if a security manager exists and its 120 * <code>checkRead</code> method denies read access to the file. 121 * @see java.io.File#getPath() 122 * @see java.lang.SecurityManager#checkRead(java.lang.String) 123 */ 124 public FileInputStream(File file) throws FileNotFoundException { 125 String name = (file != null ? file.getPath() : null); 126 SecurityManager security = System.getSecurityManager(); 127 if (security != null) { 128 security.checkRead(name); 129 } 130 if (name == null) { 131 throw new NullPointerException(); 132 } 133 if (file.isInvalid()) { 134 throw new FileNotFoundException("Invalid file path"); 135 } 136 fd = new FileDescriptor(); 137 fd.attach(this); 138 path = name; 139 open(name); 140 } 141 142 /** 143 * Creates a <code>FileInputStream</code> by using the file descriptor 144 * <code>fdObj</code>, which represents an existing connection to an 145 * actual file in the file system. 146 * <p> 147 * If there is a security manager, its <code>checkRead</code> method is 148 * called with the file descriptor <code>fdObj</code> as its argument to 149 * see if it's ok to read the file descriptor. If read access is denied 150 * to the file descriptor a <code>SecurityException</code> is thrown. 151 * <p> 152 * If <code>fdObj</code> is null then a <code>NullPointerException</code> 153 * is thrown. 154 * <p> 155 * This constructor does not throw an exception if <code>fdObj</code> 156 * is {@link java.io.FileDescriptor#valid() invalid}. 157 * However, if the methods are invoked on the resulting stream to attempt 158 * I/O on the stream, an <code>IOException</code> is thrown. 159 * 160 * @param fdObj the file descriptor to be opened for reading. 161 * @throws SecurityException if a security manager exists and its 162 * <code>checkRead</code> method denies read access to the 163 * file descriptor. 164 * @see SecurityManager#checkRead(java.io.FileDescriptor) 165 */ 166 public FileInputStream(FileDescriptor fdObj) { 167 SecurityManager security = System.getSecurityManager(); 168 if (fdObj == null) { 169 throw new NullPointerException(); 170 } 171 if (security != null) { 172 security.checkRead(fdObj); 173 } 174 fd = fdObj; 175 path = null; 176 177 /* 178 * FileDescriptor is being shared by streams. 179 * Register this stream with FileDescriptor tracker. 180 */ 181 fd.attach(this); 182 } 183 184 /** 185 * Opens the specified file for reading. 186 * @param name the name of the file 187 */ 188 private native void open0(String name) throws FileNotFoundException; 189 190 // wrap native call to allow instrumentation 191 /** 192 * Opens the specified file for reading. 193 * @param name the name of the file 194 */ 195 private void open(String name) throws FileNotFoundException { 196 open0(name); 197 } 198 199 /** 200 * Reads a byte of data from this input stream. This method blocks 201 * if no input is yet available. 202 * 203 * @return the next byte of data, or <code>-1</code> if the end of the 204 * file is reached. 205 * @exception IOException if an I/O error occurs. 206 */ 207 public int read() throws IOException { 208 return read0(); 209 } 210 211 private native int read0() throws IOException; 212 213 /** 214 * Reads a subarray as a sequence of bytes. 215 * @param b the data to be written 216 * @param off the start offset in the data 217 * @param len the number of bytes that are written 218 * @exception IOException If an I/O error has occurred. 219 */ 220 private native int readBytes(byte b[], int off, int len) throws IOException; 221 222 /** 223 * Reads up to <code>b.length</code> bytes of data from this input 224 * stream into an array of bytes. This method blocks until some input 225 * is available. 226 * 227 * @param b the buffer into which the data is read. 228 * @return the total number of bytes read into the buffer, or 229 * <code>-1</code> if there is no more data because the end of 230 * the file has been reached. 231 * @exception IOException if an I/O error occurs. 232 */ 233 public int read(byte b[]) throws IOException { 234 return readBytes(b, 0, b.length); 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 return readBytes(b, off, len); 257 } 258 259 /** 260 * Skips over and discards <code>n</code> bytes of data from the 261 * input stream. 262 * 263 * <p>The <code>skip</code> method may, for a variety of 264 * reasons, end up skipping over some smaller number of bytes, 265 * possibly <code>0</code>. If <code>n</code> is negative, the method 266 * will try to skip backwards. In case the backing file does not support 267 * backward skip at its current position, an <code>IOException</code> is 268 * thrown. The actual number of bytes skipped is returned. If it skips 269 * forwards, it returns a positive value. If it skips backwards, it 270 * returns a negative value. 271 * 272 * <p>This method may skip more bytes than what are remaining in the 273 * backing file. This produces no exception and the number of bytes skipped 274 * may include some number of bytes that were beyond the EOF of the 275 * backing file. Attempting to read from the stream after skipping past 276 * the end will result in -1 indicating the end of the file. 277 * 278 * @param n the number of bytes to be skipped. 279 * @return the actual number of bytes skipped. 280 * @exception IOException if n is negative, if the stream does not 281 * support seek, or if an I/O error occurs. 282 */ 283 public long skip(long n) throws IOException { 284 return skip0(n); 285 } 286 287 private native long skip0(long n) throws IOException; 288 289 /** 290 * Returns an estimate of the number of remaining bytes that can be read (or 291 * skipped over) from this input stream without blocking by the next 292 * invocation of a method for this input stream. Returns 0 when the file 293 * position is beyond EOF. The next invocation might be the same thread 294 * or another thread. A single read or skip of this many bytes will not 295 * 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 int available() throws IOException { 307 return available0(); 308 } 309 310 private native int available0() throws IOException; 311 312 /** 313 * Closes this file input stream and releases any system resources 314 * associated with the stream. 315 * 316 * <p> If this stream has an associated channel then the channel is closed 317 * as well. 318 * 319 * @exception IOException if an I/O error occurs. 320 * 321 * @revised 1.4 322 * @spec JSR-51 323 */ 324 public void close() throws IOException { 325 if (closed) { 326 return; 327 } 328 synchronized (closeLock) { 329 if (closed) { 330 return; 331 } 332 closed = true; 333 } 334 335 FileChannel fc = channel; 336 if (fc != null) { 337 // possible race with getChannel(), benign since 338 // FileChannel.close is final and idempotent 339 fc.close(); 340 } 341 342 fd.closeAll(new Closeable() { 343 public void close() throws IOException { 344 close0(); 345 } 346 }); 347 } 348 349 /** 350 * Returns the <code>FileDescriptor</code> 351 * object that represents the connection to 352 * the actual file in the file system being 353 * used by this <code>FileInputStream</code>. 354 * 355 * @return the file descriptor object associated with this stream. 356 * @exception IOException if an I/O error occurs. 357 * @see java.io.FileDescriptor 358 */ 359 public final FileDescriptor getFD() throws IOException { 360 if (fd != null) { 361 return fd; 362 } 363 throw new IOException(); 364 } 365 366 /** 367 * Returns the unique {@link java.nio.channels.FileChannel FileChannel} 368 * object associated with this file input stream. 369 * 370 * <p> The initial {@link java.nio.channels.FileChannel#position() 371 * position} of the returned channel will be equal to the 372 * number of bytes read from the file so far. Reading bytes from this 373 * stream will increment the channel's position. Changing the channel's 374 * position, either explicitly or by reading, will change this stream's 375 * file position. 376 * 377 * @return the file channel associated with this file input stream 378 * 379 * @since 1.4 380 * @spec JSR-51 381 */ 382 public FileChannel getChannel() { 383 FileChannel fc = this.channel; 384 if (fc == null) { 385 synchronized (this) { 386 fc = this.channel; 387 if (fc == null) { 388 this.channel = fc = FileChannelImpl.open(fd, path, true, false, this); 389 if (closed) { 390 try { 391 // possible race with close(), benign since 392 // FileChannel.close is final and idempotent 393 fc.close(); 394 } catch (IOException ioe) { 395 throw new InternalError(ioe); // should not happen 396 } 397 } 398 } 399 } 400 } 401 return fc; 402 } 403 404 private static native void initIDs(); 405 406 private native void close0() throws IOException; 407 408 static { 409 initIDs(); 410 } 411 412 /** 413 * Ensures that the <code>close</code> method of this file input stream is 414 * called when there are no more references to it. 415 * 416 * @deprecated The {@code finalize} method has been deprecated. 417 * Subclasses that override {@code finalize} in order to perform cleanup 418 * should be modified to use alternative cleanup mechanisms and 419 * to remove the overriding {@code finalize} method. 420 * When overriding the {@code finalize} method, its implementation must explicitly 421 * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. 422 * See the specification for {@link Object#finalize()} for further 423 * information about migration options. 424 * 425 * @exception IOException if an I/O error occurs. 426 * @see java.io.FileInputStream#close() 427 */ 428 @Deprecated(since="9") 429 protected void finalize() throws IOException { 430 if ((fd != null) && (fd != FileDescriptor.in)) { 431 /* if fd is shared, the references in FileDescriptor 432 * will ensure that finalizer is only called when 433 * safe to do so. All references using the fd have 434 * become unreachable. We can call close() 435 */ 436 close(); 437 } 438 } 439} 440