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 java.util.Arrays;
30 import jdk.internal.misc.Blocker;
31 import jdk.internal.util.ArraysSupport;
32 import sun.nio.ch.FileChannelImpl;
33
34 /**
35 * A {@code FileInputStream} 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} is meant for reading streams of raw bytes
40 * such as image data. For reading streams of characters, consider using
41 * {@code FileReader}.
42 *
43 * @apiNote
44 * The {@link #close} method should be called to release resources used by this
45 * stream, either directly, or with the {@code try}-with-resources statement.
46 *
47 * @implSpec
48 * Subclasses are responsible for the cleanup of resources acquired by the subclass.
49 * Subclasses requiring that resource cleanup take place after a stream becomes
50 * unreachable should use {@link java.lang.ref.Cleaner} or some other mechanism.
193
194 /*
195 * FileDescriptor is being shared by streams.
196 * Register this stream with FileDescriptor tracker.
197 */
198 fd.attach(this);
199 }
200
201 /**
202 * Opens the specified file for reading.
203 * @param name the name of the file
204 */
205 private native void open0(String name) throws FileNotFoundException;
206
207 // wrap native call to allow instrumentation
208 /**
209 * Opens the specified file for reading.
210 * @param name the name of the file
211 */
212 private void open(String name) throws FileNotFoundException {
213 long comp = Blocker.begin();
214 try {
215 open0(name);
216 } finally {
217 Blocker.end(comp);
218 }
219 }
220
221 /**
222 * Reads a byte of data from this input stream. This method blocks
223 * if no input is yet available.
224 *
225 * @return the next byte of data, or {@code -1} if the end of the
226 * file is reached.
227 * @throws IOException {@inheritDoc}
228 */
229 @Override
230 public int read() throws IOException {
231 long comp = Blocker.begin();
232 try {
233 return read0();
234 } finally {
235 Blocker.end(comp);
236 }
237 }
238
239 private native int read0() throws IOException;
240
241 /**
242 * Reads a subarray as a sequence of bytes.
243 * @param b the data to be written
244 * @param off the start offset in the data
245 * @param len the number of bytes that are written
246 * @throws IOException If an I/O error has occurred.
247 */
248 private native int readBytes(byte[] b, int off, int len) throws IOException;
249
250 /**
251 * Reads up to {@code b.length} bytes of data from this input
252 * stream into an array of bytes. This method blocks until some input
253 * is available.
254 *
255 * @param b {@inheritDoc}
256 * @return the total number of bytes read into the buffer, or
257 * {@code -1} if there is no more data because the end of
258 * the file has been reached.
259 * @throws IOException if an I/O error occurs.
260 */
261 @Override
262 public int read(byte[] b) throws IOException {
263 long comp = Blocker.begin();
264 try {
265 return readBytes(b, 0, b.length);
266 } finally {
267 Blocker.end(comp);
268 }
269 }
270
271 /**
272 * Reads up to {@code len} bytes of data from this input stream
273 * into an array of bytes. If {@code len} is not zero, the method
274 * blocks until some input is available; otherwise, no
275 * bytes are read and {@code 0} is returned.
276 *
277 * @param b {@inheritDoc}
278 * @param off {@inheritDoc}
279 * @param len {@inheritDoc}
280 * @return {@inheritDoc}
281 * @throws NullPointerException {@inheritDoc}
282 * @throws IndexOutOfBoundsException {@inheritDoc}
283 * @throws IOException if an I/O error occurs.
284 */
285 @Override
286 public int read(byte[] b, int off, int len) throws IOException {
287 long comp = Blocker.begin();
288 try {
289 return readBytes(b, off, len);
290 } finally {
291 Blocker.end(comp);
292 }
293 }
294
295 @Override
296 public byte[] readAllBytes() throws IOException {
297 long length = length();
298 long position = position();
299 long size = length - position;
300
301 if (length <= 0 || size <= 0)
302 return super.readAllBytes();
303
304 if (size > (long) Integer.MAX_VALUE) {
305 String msg =
306 String.format("Required array size too large for %s: %d = %d - %d",
307 path, size, length, position);
308 throw new OutOfMemoryError(msg);
309 }
310
311 int capacity = (int)size;
312 byte[] buf = new byte[capacity];
379 public long transferTo(OutputStream out) throws IOException {
380 long transferred = 0L;
381 if (out instanceof FileOutputStream fos) {
382 FileChannel fc = getChannel();
383 long pos = fc.position();
384 transferred = fc.transferTo(pos, Long.MAX_VALUE, fos.getChannel());
385 long newPos = pos + transferred;
386 fc.position(newPos);
387 if (newPos >= fc.size()) {
388 return transferred;
389 }
390 }
391 try {
392 return Math.addExact(transferred, super.transferTo(out));
393 } catch (ArithmeticException ignore) {
394 return Long.MAX_VALUE;
395 }
396 }
397
398 private long length() throws IOException {
399 long comp = Blocker.begin();
400 try {
401 return length0();
402 } finally {
403 Blocker.end(comp);
404 }
405 }
406 private native long length0() throws IOException;
407
408 private long position() throws IOException {
409 long comp = Blocker.begin();
410 try {
411 return position0();
412 } finally {
413 Blocker.end(comp);
414 }
415 }
416 private native long position0() throws IOException;
417
418 /**
419 * Skips over and discards {@code n} bytes of data from the
420 * input stream.
421 *
422 * <p>The {@code skip} method may, for a variety of
423 * reasons, end up skipping over some smaller number of bytes,
424 * possibly {@code 0}. If {@code n} is negative, the method
425 * will try to skip backwards. In case the backing file does not support
426 * backward skip at its current position, an {@code IOException} is
427 * thrown. The actual number of bytes skipped is returned. If it skips
428 * forwards, it returns a positive value. If it skips backwards, it
429 * returns a negative value.
430 *
431 * <p>This method may skip more bytes than what are remaining in the
432 * backing file. This produces no exception and the number of bytes skipped
433 * may include some number of bytes that were beyond the EOF of the
434 * backing file. Attempting to read from the stream after skipping past
435 * the end will result in -1 indicating the end of the file.
436 *
437 * @param n {@inheritDoc}
438 * @return the actual number of bytes skipped.
439 * @throws IOException if n is negative, if the stream does not
440 * support seek, or if an I/O error occurs.
441 */
442 @Override
443 public long skip(long n) throws IOException {
444 long comp = Blocker.begin();
445 try {
446 return skip0(n);
447 } finally {
448 Blocker.end(comp);
449 }
450 }
451
452 private native long skip0(long n) throws IOException;
453
454 /**
455 * Returns an estimate of the number of remaining bytes that can be read (or
456 * skipped over) from this input stream without blocking by the next
457 * invocation of a method for this input stream. Returns 0 when the file
458 * position is beyond EOF. The next invocation might be the same thread
459 * or another thread. A single read or skip of this many bytes will not
460 * block, but may read or skip fewer bytes.
461 *
462 * <p> In some cases, a non-blocking read (or skip) may appear to be
463 * blocked when it is merely slow, for example when reading large
464 * files over slow networks.
465 *
466 * @return an estimate of the number of remaining bytes that can be read
467 * (or skipped over) from this input stream without blocking.
468 * @throws IOException if this file input stream has been closed by calling
469 * {@code close} or an I/O error occurs.
470 */
471 @Override
472 public int available() throws IOException {
473 long comp = Blocker.begin();
474 try {
475 return available0();
476 } finally {
477 Blocker.end(comp);
478 }
479 }
480
481 private native int available0() throws IOException;
482
483 /**
484 * Closes this file input stream and releases any system resources
485 * associated with the stream.
486 *
487 * <p> If this stream has an associated channel then the channel is closed
488 * as well.
489 *
490 * @apiNote
491 * Overriding {@link #close} to perform cleanup actions is reliable
492 * only when called directly or when called by try-with-resources.
493 *
494 * @implSpec
495 * Subclasses requiring that resource cleanup take place after a stream becomes
496 * unreachable should use the {@link java.lang.ref.Cleaner} mechanism.
497 *
498 * <p>
549 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
550 * object associated with this file input stream.
551 *
552 * <p> The initial {@link java.nio.channels.FileChannel#position()
553 * position} of the returned channel will be equal to the
554 * number of bytes read from the file so far. Reading bytes from this
555 * stream will increment the channel's position. Changing the channel's
556 * position, either explicitly or by reading, will change this stream's
557 * file position.
558 *
559 * @return the file channel associated with this file input stream
560 *
561 * @since 1.4
562 */
563 public FileChannel getChannel() {
564 FileChannel fc = this.channel;
565 if (fc == null) {
566 synchronized (this) {
567 fc = this.channel;
568 if (fc == null) {
569 this.channel = fc = FileChannelImpl.open(fd, path, true,
570 false, false, this);
571 if (closed) {
572 try {
573 // possible race with close(), benign since
574 // FileChannel.close is final and idempotent
575 fc.close();
576 } catch (IOException ioe) {
577 throw new InternalError(ioe); // should not happen
578 }
579 }
580 }
581 }
582 }
583 return fc;
584 }
585
586 private static native void initIDs();
587
588 static {
589 initIDs();
590 }
|
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 java.util.Arrays;
30 import jdk.internal.util.ArraysSupport;
31 import sun.nio.ch.FileChannelImpl;
32
33 /**
34 * A {@code FileInputStream} obtains input bytes
35 * from a file in a file system. What files
36 * are available depends on the host environment.
37 *
38 * <p>{@code FileInputStream} is meant for reading streams of raw bytes
39 * such as image data. For reading streams of characters, consider using
40 * {@code FileReader}.
41 *
42 * @apiNote
43 * The {@link #close} method should be called to release resources used by this
44 * stream, either directly, or with the {@code try}-with-resources statement.
45 *
46 * @implSpec
47 * Subclasses are responsible for the cleanup of resources acquired by the subclass.
48 * Subclasses requiring that resource cleanup take place after a stream becomes
49 * unreachable should use {@link java.lang.ref.Cleaner} or some other mechanism.
192
193 /*
194 * FileDescriptor is being shared by streams.
195 * Register this stream with FileDescriptor tracker.
196 */
197 fd.attach(this);
198 }
199
200 /**
201 * Opens the specified file for reading.
202 * @param name the name of the file
203 */
204 private native void open0(String name) throws FileNotFoundException;
205
206 // wrap native call to allow instrumentation
207 /**
208 * Opens the specified file for reading.
209 * @param name the name of the file
210 */
211 private void open(String name) throws FileNotFoundException {
212 open0(name);
213 }
214
215 /**
216 * Reads a byte of data from this input stream. This method blocks
217 * if no input is yet available.
218 *
219 * @return the next byte of data, or {@code -1} if the end of the
220 * file is reached.
221 * @throws IOException {@inheritDoc}
222 */
223 @Override
224 public int read() throws IOException {
225 return read0();
226 }
227
228 private native int read0() throws IOException;
229
230 /**
231 * Reads a subarray as a sequence of bytes.
232 * @param b the data to be written
233 * @param off the start offset in the data
234 * @param len the number of bytes that are written
235 * @throws IOException If an I/O error has occurred.
236 */
237 private native int readBytes(byte[] b, int off, int len) throws IOException;
238
239 /**
240 * Reads up to {@code b.length} bytes of data from this input
241 * stream into an array of bytes. This method blocks until some input
242 * is available.
243 *
244 * @param b {@inheritDoc}
245 * @return the total number of bytes read into the buffer, or
246 * {@code -1} if there is no more data because the end of
247 * the file has been reached.
248 * @throws IOException if an I/O error occurs.
249 */
250 @Override
251 public int read(byte[] b) throws IOException {
252 return readBytes(b, 0, b.length);
253 }
254
255 /**
256 * Reads up to {@code len} bytes of data from this input stream
257 * into an array of bytes. If {@code len} is not zero, the method
258 * blocks until some input is available; otherwise, no
259 * bytes are read and {@code 0} is returned.
260 *
261 * @param b {@inheritDoc}
262 * @param off {@inheritDoc}
263 * @param len {@inheritDoc}
264 * @return {@inheritDoc}
265 * @throws NullPointerException {@inheritDoc}
266 * @throws IndexOutOfBoundsException {@inheritDoc}
267 * @throws IOException if an I/O error occurs.
268 */
269 @Override
270 public int read(byte[] b, int off, int len) throws IOException {
271 return readBytes(b, off, len);
272 }
273
274 @Override
275 public byte[] readAllBytes() throws IOException {
276 long length = length();
277 long position = position();
278 long size = length - position;
279
280 if (length <= 0 || size <= 0)
281 return super.readAllBytes();
282
283 if (size > (long) Integer.MAX_VALUE) {
284 String msg =
285 String.format("Required array size too large for %s: %d = %d - %d",
286 path, size, length, position);
287 throw new OutOfMemoryError(msg);
288 }
289
290 int capacity = (int)size;
291 byte[] buf = new byte[capacity];
358 public long transferTo(OutputStream out) throws IOException {
359 long transferred = 0L;
360 if (out instanceof FileOutputStream fos) {
361 FileChannel fc = getChannel();
362 long pos = fc.position();
363 transferred = fc.transferTo(pos, Long.MAX_VALUE, fos.getChannel());
364 long newPos = pos + transferred;
365 fc.position(newPos);
366 if (newPos >= fc.size()) {
367 return transferred;
368 }
369 }
370 try {
371 return Math.addExact(transferred, super.transferTo(out));
372 } catch (ArithmeticException ignore) {
373 return Long.MAX_VALUE;
374 }
375 }
376
377 private long length() throws IOException {
378 return length0();
379 }
380 private native long length0() throws IOException;
381
382 private long position() throws IOException {
383 return position0();
384 }
385 private native long position0() throws IOException;
386
387 /**
388 * Skips over and discards {@code n} bytes of data from the
389 * input stream.
390 *
391 * <p>The {@code skip} method may, for a variety of
392 * reasons, end up skipping over some smaller number of bytes,
393 * possibly {@code 0}. If {@code n} is negative, the method
394 * will try to skip backwards. In case the backing file does not support
395 * backward skip at its current position, an {@code IOException} is
396 * thrown. The actual number of bytes skipped is returned. If it skips
397 * forwards, it returns a positive value. If it skips backwards, it
398 * returns a negative value.
399 *
400 * <p>This method may skip more bytes than what are remaining in the
401 * backing file. This produces no exception and the number of bytes skipped
402 * may include some number of bytes that were beyond the EOF of the
403 * backing file. Attempting to read from the stream after skipping past
404 * the end will result in -1 indicating the end of the file.
405 *
406 * @param n {@inheritDoc}
407 * @return the actual number of bytes skipped.
408 * @throws IOException if n is negative, if the stream does not
409 * support seek, or if an I/O error occurs.
410 */
411 @Override
412 public long skip(long n) throws IOException {
413 return skip0(n);
414 }
415
416 private native long skip0(long n) throws IOException;
417
418 /**
419 * Returns an estimate of the number of remaining bytes that can be read (or
420 * skipped over) from this input stream without blocking by the next
421 * invocation of a method for this input stream. Returns 0 when the file
422 * position is beyond EOF. The next invocation might be the same thread
423 * or another thread. A single read or skip of this many bytes will not
424 * block, but may read or skip fewer bytes.
425 *
426 * <p> In some cases, a non-blocking read (or skip) may appear to be
427 * blocked when it is merely slow, for example when reading large
428 * files over slow networks.
429 *
430 * @return an estimate of the number of remaining bytes that can be read
431 * (or skipped over) from this input stream without blocking.
432 * @throws IOException if this file input stream has been closed by calling
433 * {@code close} or an I/O error occurs.
434 */
435 @Override
436 public int available() throws IOException {
437 return available0();
438 }
439
440 private native int available0() throws IOException;
441
442 /**
443 * Closes this file input stream and releases any system resources
444 * associated with the stream.
445 *
446 * <p> If this stream has an associated channel then the channel is closed
447 * as well.
448 *
449 * @apiNote
450 * Overriding {@link #close} to perform cleanup actions is reliable
451 * only when called directly or when called by try-with-resources.
452 *
453 * @implSpec
454 * Subclasses requiring that resource cleanup take place after a stream becomes
455 * unreachable should use the {@link java.lang.ref.Cleaner} mechanism.
456 *
457 * <p>
508 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
509 * object associated with this file input stream.
510 *
511 * <p> The initial {@link java.nio.channels.FileChannel#position()
512 * position} of the returned channel will be equal to the
513 * number of bytes read from the file so far. Reading bytes from this
514 * stream will increment the channel's position. Changing the channel's
515 * position, either explicitly or by reading, will change this stream's
516 * file position.
517 *
518 * @return the file channel associated with this file input stream
519 *
520 * @since 1.4
521 */
522 public FileChannel getChannel() {
523 FileChannel fc = this.channel;
524 if (fc == null) {
525 synchronized (this) {
526 fc = this.channel;
527 if (fc == null) {
528 fc = FileChannelImpl.open(fd, path, true, false, false, false, this);
529 this.channel = fc;
530 if (closed) {
531 try {
532 // possible race with close(), benign since
533 // FileChannel.close is final and idempotent
534 fc.close();
535 } catch (IOException ioe) {
536 throw new InternalError(ioe); // should not happen
537 }
538 }
539 }
540 }
541 }
542 return fc;
543 }
544
545 private static native void initIDs();
546
547 static {
548 initIDs();
549 }
|