45 * @see java.io.FileOutputStream 46 * @see java.nio.file.Files#newInputStream 47 * @since 1.0 48 */ 49 public 50 class FileInputStream extends InputStream 51 { 52 /* File Descriptor - handle to the open file */ 53 private final FileDescriptor fd; 54 55 /** 56 * The path of the referenced file 57 * (null if the stream is created with a file descriptor) 58 */ 59 private final String path; 60 61 private volatile FileChannel channel; 62 63 private final AtomicBoolean closed = new AtomicBoolean(false); 64 65 /** 66 * Creates a <code>FileInputStream</code> by 67 * opening a connection to an actual file, 68 * the file named by the path name <code>name</code> 69 * in the file system. A new <code>FileDescriptor</code> 70 * object is created to represent this file 71 * connection. 72 * <p> 73 * First, if there is a security 74 * manager, its <code>checkRead</code> method 75 * is called with the <code>name</code> argument 76 * as its argument. 77 * <p> 78 * If the named file does not exist, is a directory rather than a regular 79 * file, or for some other reason cannot be opened for reading then a 80 * <code>FileNotFoundException</code> is thrown. 81 * 82 * @param name the system-dependent file name. 83 * @exception FileNotFoundException if the file does not exist, 84 * is a directory rather than a regular file, 85 * or for some other reason cannot be opened for 86 * reading. 87 * @exception SecurityException if a security manager exists and its 88 * <code>checkRead</code> method denies read access 89 * to the file. 90 * @see java.lang.SecurityManager#checkRead(java.lang.String) 91 */ 92 public FileInputStream(String name) throws FileNotFoundException { 93 this(name != null ? new File(name) : null); 94 } 95 96 /** 97 * Creates a <code>FileInputStream</code> by 98 * opening a connection to an actual file, 99 * the file named by the <code>File</code> 100 * object <code>file</code> in the file system. 101 * A new <code>FileDescriptor</code> object 102 * is created to represent this file connection. 103 * <p> 104 * First, if there is a security manager, 105 * its <code>checkRead</code> method is called 106 * with the path represented by the <code>file</code> 107 * argument as its argument. 108 * <p> 109 * If the named file does not exist, is a directory rather than a regular 110 * file, or for some other reason cannot be opened for reading then a 111 * <code>FileNotFoundException</code> is thrown. 112 * 113 * @param file the file to be opened for reading. 114 * @exception FileNotFoundException if the file does not exist, 115 * is a directory rather than a regular file, 116 * or for some other reason cannot be opened for 117 * reading. 118 * @exception SecurityException if a security manager exists and its 119 * <code>checkRead</code> method denies read access to the file. 120 * @see java.io.File#getPath() 121 * @see java.lang.SecurityManager#checkRead(java.lang.String) 122 */ 123 public FileInputStream(File file) throws FileNotFoundException { 124 String name = (file != null ? file.getPath() : null); 125 SecurityManager security = System.getSecurityManager(); 126 if (security != null) { 127 security.checkRead(name); 128 } 129 if (name == null) { 130 throw new NullPointerException(); 131 } 132 if (file.isInvalid()) { 133 throw new FileNotFoundException("Invalid file path"); 134 } 135 fd = new FileDescriptor(); 136 fd.attach(this); 137 path = name; 138 open(name); 139 } 140 141 /** 142 * Creates a <code>FileInputStream</code> by using the file descriptor 143 * <code>fdObj</code>, which represents an existing connection to an 144 * actual file in the file system. 145 * <p> 146 * If there is a security manager, its <code>checkRead</code> method is 147 * called with the file descriptor <code>fdObj</code> as its argument to 148 * see if it's ok to read the file descriptor. If read access is denied 149 * to the file descriptor a <code>SecurityException</code> is thrown. 150 * <p> 151 * If <code>fdObj</code> is null then a <code>NullPointerException</code> 152 * is thrown. 153 * <p> 154 * This constructor does not throw an exception if <code>fdObj</code> 155 * is {@link java.io.FileDescriptor#valid() invalid}. 156 * However, if the methods are invoked on the resulting stream to attempt 157 * I/O on the stream, an <code>IOException</code> is thrown. 158 * 164 */ 165 public FileInputStream(FileDescriptor fdObj) { 166 SecurityManager security = System.getSecurityManager(); 167 if (fdObj == null) { 168 throw new NullPointerException(); 169 } 170 if (security != null) { 171 security.checkRead(fdObj); 172 } 173 fd = fdObj; 174 path = null; 175 176 /* 177 * FileDescriptor is being shared by streams. 178 * Register this stream with FileDescriptor tracker. 179 */ 180 fd.attach(this); 181 } 182 183 /** 184 * Opens the specified file for reading. 185 * @param name the name of the file 186 */ 187 private native void open0(String name) throws FileNotFoundException; 188 189 // wrap native call to allow instrumentation 190 /** 191 * Opens the specified file for reading. 192 * @param name the name of the file 193 */ 194 private void open(String name) throws FileNotFoundException { 195 open0(name); 196 } 197 198 /** 199 * Reads a byte of data from this input stream. This method blocks 200 * if no input is yet available. 201 * 202 * @return the next byte of data, or <code>-1</code> if the end of the 203 * file is reached. 204 * @exception IOException if an I/O error occurs. 205 */ 206 public int read() throws IOException { 207 return read0(); 208 } 209 210 private native int read0() throws IOException; 211 212 /** 213 * Reads a subarray as a sequence of bytes. 214 * @param b the data to be written 215 * @param off the start offset in the data 216 * @param len the number of bytes that are written 217 * @exception IOException If an I/O error has occurred. 218 */ 219 private native int readBytes(byte b[], int off, int len) throws IOException; 220 221 /** 222 * Reads up to <code>b.length</code> bytes of data from this input 223 * stream into an array of bytes. This method blocks until some input 224 * is available. 225 * 226 * @param b the buffer into which the data is read. 227 * @return the total number of bytes read into the buffer, or 228 * <code>-1</code> if there is no more data because the end of 229 * the file has been reached. 230 * @exception IOException if an I/O error occurs. 231 */ 232 public int read(byte b[]) throws IOException { 233 return readBytes(b, 0, b.length); 234 } 235 236 /** 237 * Reads up to <code>len</code> bytes of data from this input stream 238 * into an array of bytes. If <code>len</code> is not zero, the method 239 * blocks until some input is available; otherwise, no 240 * bytes are read and <code>0</code> is returned. 241 * 242 * @param b the buffer into which the data is read. 243 * @param off the start offset in the destination array <code>b</code> 244 * @param len the maximum number of bytes read. 245 * @return the total number of bytes read into the buffer, or 246 * <code>-1</code> if there is no more data because the end of 247 * the file has been reached. 248 * @exception NullPointerException If <code>b</code> is <code>null</code>. 249 * @exception IndexOutOfBoundsException If <code>off</code> is negative, 250 * <code>len</code> is negative, or <code>len</code> is greater than 251 * <code>b.length - off</code> 252 * @exception IOException if an I/O error occurs. 253 */ 254 public int read(byte b[], int off, int len) throws IOException { 255 return readBytes(b, off, len); 256 } 257 258 /** 259 * Skips over and discards <code>n</code> bytes of data from the 260 * input stream. 261 * 262 * <p>The <code>skip</code> method may, for a variety of 263 * reasons, end up skipping over some smaller number of bytes, 264 * possibly <code>0</code>. If <code>n</code> is negative, the method 265 * will try to skip backwards. In case the backing file does not support 266 * backward skip at its current position, an <code>IOException</code> is 267 * thrown. The actual number of bytes skipped is returned. If it skips 268 * forwards, it returns a positive value. If it skips backwards, it 269 * returns a negative value. 270 * 271 * <p>This method may skip more bytes than what are remaining in the 272 * backing file. This produces no exception and the number of bytes skipped 273 * may include some number of bytes that were beyond the EOF of the 274 * backing file. Attempting to read from the stream after skipping past | 45 * @see java.io.FileOutputStream 46 * @see java.nio.file.Files#newInputStream 47 * @since 1.0 48 */ 49 public 50 class FileInputStream extends InputStream 51 { 52 /* File Descriptor - handle to the open file */ 53 private final FileDescriptor fd; 54 55 /** 56 * The path of the referenced file 57 * (null if the stream is created with a file descriptor) 58 */ 59 private final String path; 60 61 private volatile FileChannel channel; 62 63 private final AtomicBoolean closed = new AtomicBoolean(false); 64 65 private boolean direct = false; 66 67 private int pageSize = -1; 68 /** 69 * Creates a <code>FileInputStream</code> by 70 * opening a connection to an actual file, 71 * the file named by the path name <code>name</code> 72 * in the file system. A new <code>FileDescriptor</code> 73 * object is created to represent this file 74 * connection. 75 * <p> 76 * First, if there is a security 77 * manager, its <code>checkRead</code> method 78 * is called with the <code>name</code> argument 79 * as its argument. 80 * <p> 81 * If the named file does not exist, is a directory rather than a regular 82 * file, or for some other reason cannot be opened for reading then a 83 * <code>FileNotFoundException</code> is thrown. 84 * 85 * @param name the system-dependent file name. 86 * @exception FileNotFoundException if the file does not exist, 87 * is a directory rather than a regular file, 88 * or for some other reason cannot be opened for 89 * reading. 90 * @exception SecurityException if a security manager exists and its 91 * <code>checkRead</code> method denies read access 92 * to the file. 93 * @see java.lang.SecurityManager#checkRead(java.lang.String) 94 */ 95 public FileInputStream(String name) throws FileNotFoundException { 96 this(name != null ? new File(name) : null); 97 } 98 99 /** 100 * Creates a <code>FileInputStream</code> by 101 * opening a connection to an actual file, 102 * the file named by the path name <code>name</code> 103 * in the file system. If the second parameter is 104 * <code>true</code>, bytes are directly read from 105 * storage media. A new <code>FileDescriptor</code> 106 * object is created to represent this file connection. 107 * <p> 108 * First, if there is a security 109 * manager, its <code>checkRead</code> method 110 * is called with the <code>name</code> argument 111 * as its argument. 112 * <p> 113 * If the named file does not exist, is a directory rather than a regular 114 * file, or for some other reason cannot be opened for reading then a 115 * <code>FileNotFoundException</code> is thrown. 116 * 117 * @param name the system-dependent file name. 118 * @param direct if <code>true</code>, then bytes will be read 119 * directly to storage media 120 * @exception FileNotFoundException if the file does not exist, 121 * is a directory rather than a regular file, 122 * or for some other reason cannot be opened for 123 * reading. 124 * @exception SecurityException if a security manager exists and its 125 * <code>checkRead</code> method denies read access 126 * to the file. 127 * @see java.lang.SecurityManager#checkRead(java.lang.String) 128 * @since 1.9 129 */ 130 public FileInputStream(String name, boolean direct) throws FileNotFoundException { 131 this(name != null ? new File(name): null, direct); 132 } 133 134 /** 135 * Creates a <code>FileInputStream</code> by 136 * opening a connection to an actual file, 137 * the file named by the <code>File</code> 138 * object <code>file</code> in the file system. 139 * A new <code>FileDescriptor</code> object 140 * is created to represent this file connection. 141 * <p> 142 * First, if there is a security manager, 143 * its <code>checkRead</code> method is called 144 * with the path represented by the <code>file</code> 145 * argument as its argument. 146 * <p> 147 * If the named file does not exist, is a directory rather than a regular 148 * file, or for some other reason cannot be opened for reading then a 149 * <code>FileNotFoundException</code> is thrown. 150 * 151 * @param file the file to be opened for reading. 152 * @exception FileNotFoundException if the file does not exist, 153 * is a directory rather than a regular file, 154 * or for some other reason cannot be opened for 155 * reading. 156 * @exception SecurityException if a security manager exists and its 157 * <code>checkRead</code> method denies read access to the file. 158 * @see java.io.File#getPath() 159 * @see java.lang.SecurityManager#checkRead(java.lang.String) 160 */ 161 public FileInputStream(File file) throws FileNotFoundException { 162 this(file, false); 163 } 164 165 /** 166 * Creates a <code>FileInputStream</code> by using the file descriptor 167 * <code>fdObj</code>, which represents an existing connection to an 168 * actual file in the file system. 169 * <p> 170 * If there is a security manager, its <code>checkRead</code> method is 171 * called with the file descriptor <code>fdObj</code> as its argument to 172 * see if it's ok to read the file descriptor. If read access is denied 173 * to the file descriptor a <code>SecurityException</code> is thrown. 174 * <p> 175 * If <code>fdObj</code> is null then a <code>NullPointerException</code> 176 * is thrown. 177 * <p> 178 * This constructor does not throw an exception if <code>fdObj</code> 179 * is {@link java.io.FileDescriptor#valid() invalid}. 180 * However, if the methods are invoked on the resulting stream to attempt 181 * I/O on the stream, an <code>IOException</code> is thrown. 182 * 188 */ 189 public FileInputStream(FileDescriptor fdObj) { 190 SecurityManager security = System.getSecurityManager(); 191 if (fdObj == null) { 192 throw new NullPointerException(); 193 } 194 if (security != null) { 195 security.checkRead(fdObj); 196 } 197 fd = fdObj; 198 path = null; 199 200 /* 201 * FileDescriptor is being shared by streams. 202 * Register this stream with FileDescriptor tracker. 203 */ 204 fd.attach(this); 205 } 206 207 /** 208 * Creates a <code>FileInputStream</code> by opening a connection to an 209 * actual file with O_DIRECT option, the file named by the <code> 210 * File</code> object <code>file </code> in the file system. A new <code> 211 * FileDescriptor</code> object is created to represent this file connection. 212 * <p> 213 * First, if there is a security manager, its <code>checkRead</code> 214 * method is called with the path represented by the <code>file</code> 215 * argument as its argument. 216 * <p> 217 * If the named file does not exist, is a directory rather than a regular 218 * file, or for some other reason cannot be opened for reading then a 219 * <code>FileNotFoundException</code> is thrown. 220 * @param file the file to be opened for reading. 221 * @param direct if <code>true</code>, then bytes will be read 222 * directly to storage media 223 * @exception FileNotFoundException if the file does not exist, is a 224 * directory rather than a regular file, or for some 225 * other reason cannot be opened for reading. 226 * @exception SecurityException if a security manager exists 227 */ 228 public FileInputStream(File file, boolean direct) throws FileNotFoundException { 229 this.direct = direct; 230 if (direct) { 231 getPageSize(); 232 } 233 String name = (file != null ? file.getPath() : null); 234 SecurityManager security = System.getSecurityManager(); 235 if (security != null) { 236 security.checkRead(name); 237 } 238 if (name == null) { 239 throw new NullPointerException(); 240 } 241 if (file.isInvalid()) { 242 throw new FileNotFoundException("Invalid file path"); 243 } 244 fd = new FileDescriptor(); 245 fd.attach(this); 246 path = name; 247 open(name); 248 } 249 250 /** 251 * Opens the specified file for reading. 252 * @param name the name of the file 253 */ 254 private native void open0(String name, boolean direct) throws FileNotFoundException; 255 256 // wrap native call to allow instrumentation 257 /** 258 * Opens the specified file for reading. 259 * @param name the name of the file 260 */ 261 private void open(String name) throws FileNotFoundException { 262 open0(name, direct); 263 } 264 265 private native int getPageSize0(); 266 267 private int getPageSize() { 268 if (pageSize == -1) { 269 pageSize = getPageSize0(); 270 } 271 return this.pageSize; 272 } 273 274 /** 275 * Reads a byte of data from this input stream. This method blocks 276 * if no input is yet available. 277 * 278 * @return the next byte of data, or <code>-1</code> if the end of the 279 * file is reached. 280 * @exception IOException if an I/O error occurs. 281 */ 282 public int read() throws IOException { 283 return read0(); 284 } 285 286 private native int read0() throws IOException; 287 288 /** 289 * Reads a subarray as a sequence of bytes. 290 * @param b the data to be written 291 * @param off the start offset in the data 292 * @param len the number of bytes that are written 293 * @exception IOException If an I/O error has occurred. 294 */ 295 private native int readBytes(byte b[], int off, int len) throws IOException; 296 297 /** 298 * Reads a subarray as a sequence of bytes with DirectIO. 299 * @param b the data to be written 300 * @param off the start offset in the data 301 * @param len the number of bytes that are written 302 * @exception IOException If an I/O error has occurred. 303 */ 304 private native int readBytesD(byte b[], int off, int len) throws IOException; 305 306 /** 307 * Reads up to <code>b.length</code> bytes of data from this input 308 * stream into an array of bytes. This method blocks until some input 309 * is available. 310 * 311 * @param b the buffer into which the data is read. 312 * @return the total number of bytes read into the buffer, or 313 * <code>-1</code> if there is no more data because the end of 314 * the file has been reached. 315 * @exception IOException if an I/O error occurs. 316 */ 317 public int read(byte b[]) throws IOException { 318 if (direct) 319 return readBytesD(b, 0, b.length); 320 return readBytes(b, 0, b.length); 321 } 322 323 /** 324 * Reads up to <code>len</code> bytes of data from this input stream 325 * into an array of bytes. If <code>len</code> is not zero, the method 326 * blocks until some input is available; otherwise, no 327 * bytes are read and <code>0</code> is returned. 328 * 329 * @param b the buffer into which the data is read. 330 * @param off the start offset in the destination array <code>b</code> 331 * @param len the maximum number of bytes read. 332 * @return the total number of bytes read into the buffer, or 333 * <code>-1</code> if there is no more data because the end of 334 * the file has been reached. 335 * @exception NullPointerException If <code>b</code> is <code>null</code>. 336 * @exception IndexOutOfBoundsException If <code>off</code> is negative, 337 * <code>len</code> is negative, or <code>len</code> is greater than 338 * <code>b.length - off</code> 339 * @exception IOException if an I/O error occurs. 340 */ 341 public int read(byte b[], int off, int len) throws IOException { 342 if (direct) 343 return readBytesD(b, off, len); 344 return readBytes(b, off, len); 345 } 346 347 /** 348 * Skips over and discards <code>n</code> bytes of data from the 349 * input stream. 350 * 351 * <p>The <code>skip</code> method may, for a variety of 352 * reasons, end up skipping over some smaller number of bytes, 353 * possibly <code>0</code>. If <code>n</code> is negative, the method 354 * will try to skip backwards. In case the backing file does not support 355 * backward skip at its current position, an <code>IOException</code> is 356 * thrown. The actual number of bytes skipped is returned. If it skips 357 * forwards, it returns a positive value. If it skips backwards, it 358 * returns a negative value. 359 * 360 * <p>This method may skip more bytes than what are remaining in the 361 * backing file. This produces no exception and the number of bytes skipped 362 * may include some number of bytes that were beyond the EOF of the 363 * backing file. Attempting to read from the stream after skipping past |