2

下面的一段代码用于阅读Files

 int bytesRead;
 byte[] bytes = new byte[1000];  //buffer
 FileInputStream fis = new FileInputStream(uploadedFile);

    while ((bytesRead = fis.read(bytes)) != -1) {
          fis.read(bytes, 0, bytesRead);
    }

fis.close();

根据read() 方法的 api

从此输入流中读取最多 b.length 个字节的数据到字节数组中。此方法会阻塞,直到某些输入可用。

没有指定它重新bytes填充数组的位置,但流填充array 直到file成功read.

但是它在内部是如何维持这个魔法的呢?

我看到源代码或阅读方法

public int More ...read(byte b[]) throws IOException {
214        return readBytes(b, 0, b.length);
215    }

readBytes的源代码是

200    private native int More ...readBytes
                (byte b[], int off, int len) throws IOException;

有注意到提到如何bytes..

我上传了一个 500MB 的文件,没有任何问题,分配了那个1000字节array

4

2 回答 2

1

如果您问为什么可以读取大约 1 KB 缓冲区的 ~500 MB 文件,那是因为每次循环时都会覆盖缓冲区的内容(大约 500,000 次)。

如果您要询问 read 函数是如何实际实现的,请注意底层调用包含关键字native。这意味着通过 JNI 调用本机代码。确切的实现将取决于 JVM 和操作系统。

于 2013-08-07T14:30:04.593 回答
1

Michael Schaeffer发表了一篇很棒的文章readBytes

简而言之:

Java 中的文件 I/O 是通过读取本地缓冲区,然后从本地缓冲区复制到最初传递给 int read(byte byf[]) 的 Java byte[] 来实现的。这种双重复制很慢,但如果读取缓冲区大于 8K,它还需要堆分配第二个读取缓冲区。

许多其他有用的细节要提及,但它更容易阅读。

于 2013-08-07T14:33:12.650 回答