【问题标题】:How the buffer byte array is continuously filling while streaming?流式传输时缓冲区字节数组如何连续填充?
【发布时间】:2013-08-12 19:14:07
【问题描述】:

下面这段代码用于读取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();

根据api of read() method

从此输入流中读取最多 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

【问题讨论】:

  • 字节数组被重新填充的唯一原因是你在一个while循环中进行读取调用,直到整个文件被读取后才会中断。
  • 从此输入流中读取最多 b.length 个字节的数据到一个字节数组中 这意味着它会填充给定的byte[]
  • @SotiriosDelimanolis 是的,它显示,它应该重新填充后对吗?纠正我如果我错了..新的流。
  • 您可能想阅读此question问题
  • 每次while 循环,您的byte[] 将包含流中的下一个字节。

标签: java file streaming


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    readBytes 上的 great articleMichael Schaeffer 发布

    简而言之:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      相关资源
      最近更新 更多