如何保持读取具有动态缓冲区大小的大文件 - 取决于从文件读取的数据。

时间:2017-02-09 17:06:21

标签: java fileinputstream bufferedinputstream

我有一个包含数据的文件,这些数据仅在某个大小的块中有意义,这些块附加在每个块的开头,例如,

{chunk_1_size}
{chunk_1}
{chunk_2_size}
{chunk_2}
{chunk_3_size}
{chunk_3}
{chunk_4_size}
{chunk_4}
{chunk_5_size}
{chunk_5}
.
.
{chunk_n_size}
{chunk_n}

文件非常大~2GB,块大小约为20MB(这是我想要的缓冲区)

我想缓冲读取此文件以减少调用实际硬盘的次数。

但我不确定要有多少缓冲区,因为块大小可能会有所不同。

我想到的伪代码:

while(!EOF) {
    /*chunk is an integer i.e. 4 bytes*/
    readChunkSize(); 
    /*according to chunk size read the number of bytes from file*/
    readChunk(chunkSize);   
}

如果我说我有随机缓冲区大小,那么我可能会陷入以下情况:

  1. 第一个缓冲区包含chunkSize_1 + chunk_1 + partialChunk_2 ---我必须跟踪剩余的,然后从下一个缓冲区获取重新生成的块并连接到剩余部分以完成块
  2. 第一个缓冲区包含chunkSize_1 + chunk_1 + partialChunkSize_2(块大小是一个整数,即4个字节,所以我只得到第一个缓冲区中的两个)---我必须跟踪partialChunkSize_2,然后从中获取重新生成的字节下一个缓冲区形成一个实际上给我下一个chunkSize的整数
  3. 缓冲区甚至可能无法一次获得一个整块 - 我必须继续按下读取,直到第一个块完全读入内存

2 个答案:

答案 0 :(得分:0)

您无法控制对硬盘的调用次数。您和硬盘之间有几层(操作系统,驱动程序,硬件缓冲),您无法控制。

在Java代码(1M)中设置合理的缓冲区大小并忘记它,除非您证明存在与缓冲区大小直接相关的性能问题。换句话说,不要陷入premature optimization的陷阱。

另见https://stackoverflow.com/a/385529/18157

答案 1 :(得分:0)

您可能需要进行一些分析,并了解平均缓冲区大小,以便读取数据。 你要说的是保持缓冲区大小并读取数据直到块完成,以获得完整数据的含义 您是否将文件复制到其他地方,或者将此数据发送到其他地方? 对于某些活动,Java NIO包具有更好的实现来处理,而不是将数据读入jvm缓冲区。 缓冲区大小应足以读取最大数据块, 如果计划在memmory中保存数据,使用缓冲区读取数据并将其保存在内存中仍将是内存成本操作,则可以使用基本刷新操作以多种方式释放缓冲区。 另请检查apache file-utils以读/写数据