结论数组缓冲区不能超过1024*1024

背景:众所周知,读写文件的标准基础代码

InputStream inputStream = new FileInputStream(new File("fileInPath"))
    OutputStream outputStream = new FileOutputStream(new File("fileOutPath"));
    int read = 0;
    byte[] bytes = new byte[1024*1024];
    while ((read = inputStream.read(bytes)) != -1) {
        outputStream.write(bytes, 0, read);
    }
    outputStream.flush();
    outputStream.close();
    inputStream.close();

对于缓冲数组的大小,越大,读写次数越少,但消耗内存越多.
所以缓冲数组应该多大呢
1.一定是1024的整数倍
2.BufferedInputStream中使用 8*1024
3.android 存在jni,因此 可能需要考虑这个信息,C/VC++ 将一个文件超过2M内容读到一个数组中,当定义数组大小超过1024*1024时,程式都会抛出异常挂掉:由于数组为局部变量时使用的是栈内存导致的 4.与文件系统块大小、CPU缓存大小和缓存延迟 有关

大多数文件系统配置为使用4096或8192的块大小。理论上,如果配置缓冲区大小,以便比磁盘块多读几个字节,那么对文件系统的操作可能效率极低(也就是说,如果将缓冲区配置为一次读取4100字节,则每次读取将需要由文件系统读取2个块)。这些块已经在缓存中,然后将支付RAM->L3/L2缓存延迟的代价。

这就是为什么大多数缓冲区大小为2的原因,并且通常大于(或等于)磁盘块大小。这意味着你的流读取可能导致多个磁盘块读取--但这些读取总是使用一个完整的块--不会浪费读取。

现在,在典型的流场景中,这被抵消了很大一部分,因为当您进入下一次读取时,从磁盘读取的块仍将在内存中(毕竟,我们在这里进行顺序读取)--所以最终在下一次读取时支付RAM->L3/L2缓存延迟价格,而不是磁盘->RAM延迟。磁盘->RAM延迟太慢,几乎淹没了可能处理的任何其他延迟。

因此 为了兼顾性能和安全性.最小定义1024,最大定义1024*1024

Tips 用啥方式读写文件,速度比较快
小数组+FileInputStream 小数组+BufferedInputStream
小数组+BufferedReader
BufferedReader字符流按行