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