今天是五一假期的第一天。这本来应该是一个热闹、好玩的日子,但作为一个和北漂一起在北京的开发者,实在很难想到去那里玩。好玩的地方很远,但近处却觉得无聊。那么,等我有空了,就写一篇文章,总结一下我昨天写的程序吧。
我的朋友昨天下午跟我说话。他说他有一个需要将G上的txt文件读写到数据库中。使用普通io的结果自然是OOM,所以我果断使用NIO技术。为了提高速度,自然要使用多线程技术。
接下来介绍一下实现思路以及相关知识点。
1。分区文件
为了充分利用多线程读取,需要将文件划分为多个区域供每个线程读取。那么就需要一个算法来计算每个线程读取的起始位置和结束位置。然后首先根据配置的线程数和文件总长度计算分配给每个线程的平均读取长度。但有一件事。由于该文件是纯文本文件,因此必须逐行处理。如果分割点在某一行的中间,那么该行数据就会被分成两部分,由两个线程同时处理。这种情况不可能发生。的。因此,每个区域结束点的字符必须是换行符。第一个区域的起始位置为0,结束位置首先设置为(文件长度/线程数)。如果结束点位置不是换行符,则只能加1,直到是换行符位置。现在我们有了第一个区域的结束位置,自然就可以找到第二个区域的开始位置了。同理,我们可以根据上面的算法找到第二个区域的结束位置,然后依次类推第三个和第四个区域。 ......
上述算法中,只有确定了第一个区域的结束位置才能确定第二个区域的开始位置,只有确定了第二个区域的结束位置才能确定第三个区域的开始位置予以确定,等等。下去。根据这个规则,自然想到的就是用递归来解决。 (详情见源码)
2。内存文件映射
简单说一下内存文件映射:
在我读取大文件的实现中,我使用了Java的内存映射API,这样当我们要读取某个地址时,就可以将内容加载到内存中。无需一次加载全部内容。
以上是我使用的主要思路和一些技术点。可能有表达不清楚的地方,请见谅^_^
具体实现请参考代码。这里是代码地址(Java读取大文件)
-->