文章目录
一、大文件读取之文件分割法
二、大文件读取之多线程读取
三、悟纤小结
一、大文件读取之文件分割法
我们来看下这种方法的核心思路就是:不是文件太大了嘛?那么是否可以把文件拆分成几个小的文件,然后使用多线程进行读取呐?具体的步骤:
(1)先分割成多个文件。
(2)多个线程操作多个文件,避免两个线程操作同一个文件
(3)按行读文件
1.1 文件分割
在Mac和Linux都有文件分割的命令,可以使用:
split -b 1024m test2.txt /data/tmp/my/test.txt.
说明:
(1)split:分割命令;
(2)-b 1024m:指定每多少字就要切成一个小文件。支持单位:m,k;这里是将6.5G的文件按照1G进行拆分成7个文件左右。
(3)test2.txt:要分割的文件;
(4)test.txt. : 切割后文件的前置文件名,split会自动在前置文件名后再加上编号;
其它参数:
(1)-l<行数> : 指定每多少行就要切成一个小文件。
(2) -C<字节>:与-b参数类似,但切割时尽量维持每行的完整性。
分割成功之后文件是这样子的:
1.2 多线程读取分割文件
我们使用多线程读取分割的文件,然后开启线程对每个文件进行处理:
-
public void readFileBySplitFile(String pathname) {
-
//pathname这里是路径,非具体的文件名,比如:/data/tmp/my
-
File file = new File(pathname);
-
File[] files = file.listFiles();
-
List<MyThread> threads = new ArrayList<>();
-
for(File f:files) {
-
MyThread thread = new MyThread(f.getPath());
-
threads.add(thread);
-
thread.start();
-
}
-
for(MyThread t:threads) {
-
try {
-
t.join();
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
private class MyThread extends Thread{
-
private String pathname;
-
public MyThread(String pathname) {
-
this.pathname = pathname;
-
}
-
@Override
-
public void run() {
-
readFileFileChannel(pathname);
-
}
-
}
说明:
(1)获取到指定目录下的所有分割的文件信息;
(2)遍历文件路径,将路径使用线程进行处理,这里线程的run使用readFileChannel进行读取每个文件的信息。
(3)join方法:就是让所有线程等待,然后回到主线程,不懂的可以参之前的一篇文章:《悟纤和师傅去女儿国「线程并行变为串行,Thread你好牛」》
测试:6.5G 耗时:4秒
这个多线程的方式,那么理论上是文件越大,优势会越明显。对于线程开启的个数,这里使用的是文件的个数,在实际中,能这么使用嘛?答案肯定是不行的。相信大家应该知道怎么进行改良下,这里不展开讲解。
。。。。。。。。。。。。。。。。。
版权原因,完整文章,请参考如下:100G的文件如何读取续集 - 第307篇