【发布时间】:2014-05-30 22:36:59
【问题描述】:
我有一个 25GB 的 CSV 文件。我知道文件中有大约 5 亿条记录。
我想对数据进行一些基本分析。没什么太花哨的。
我不想使用 Hadoop/Pig,至少现在还不想。
我编写了一个 java 程序来同时进行分析。这就是我正在做的事情。
class MainClass {
public static void main(String[] args) {
long start = 1;
long increment = 10000000;
OpenFileAndDoStuff a = new OpenFileAndDoStuff[50];
for(int i=0;i<50;i++) {
a[i] = new OpenFileAndDoStuff("path/to/50GB/file.csv",start,start+increment-1);
a[i].start();
start += increment;
}
for(OpenFileAndDoStuff obj : a) {
obj.join();
}
//do aggregation
}
}
class OpenFileAndDoStuff extends Thread {
volatile HashMap<Integer, Integer> stuff = new HashMap<>();
BufferedReader _br;
long _end;
OpenFileAndDoStuff(String filename, long startline, long endline) throws IOException, FileNotFoundException {
_br = new BufferedReader(new FileReader(filename));
long counter=0;
//move the bufferedReader pointer to the startline specified
while(counter++ < start)
_br.readLine();
this._end = end;
}
void doStuff() {
//read from buffered reader until end of file or until the specified endline is reached and do stuff
}
public void run() {
doStuff();
}
public HashMap<Integer, Integer> getStuff() {
return stuff;
}
}
我想这样做我可以打开 50 个缓冲读取器,所有这些都并行读取 1000 万行卡盘,一旦它们都完成了它们的工作,我就会聚合它们。
但是,我面临的问题是,即使我要求启动 50 个线程,但一次只有两个启动,并且一次可以从文件中读取。
有没有办法让所有 50 个文件同时打开并读取文件?为什么我一次只能阅读两个读者?
该文件位于 Windows 8 机器上,而 java 也在同一台机器上。
有什么想法吗?
【问题讨论】:
-
@etherous 我已经在尝试并这样做了,但是我不能同时从文件中读取两个以上的 bufferedReader。请参阅有关我如何操作的说明。你的评论就像有人告诉我宇宙中某处存在一块完美的圆形石头一样含糊。
-
在这种情况下,如果不使用 NIO,您只会走这么远。我会使用 FileChannel。你想要一个例子吗?编辑:docs.oracle.com/javase/tutorial/essential/io/rafs.html
-
@etherous 当然。我现在正在 oracle 文档上查找它,但是一个例子会很棒。但是,这正是我想要的。感谢您指出正确的方向!
-
我提供的链接与您可能想要的非常接近。您需要做的唯一修改是创建多个实例并为每个实例分区文件
-
看来这个文件有效地作为一个链表工作。因此,您告诉要处理 400 万至 500 万行的线程也必须实际读取前 400 万行。我不相信您将能够实现高水平的并发性,除非您可以对文件进行“索引”访问。然后,您可以使用 FileChannel 或 RandomAccessFile 打开文件,并专门跳转到该线程应该处理的文件部分。