我有一个非常大的CSV文件(1GB +),它有100,000行。
我需要编写一个Java程序来解析CSV文件中的每一行,以便为HTTP请求发送一个正文。
换句话说,我需要发送100,000个HTTP请求,这些请求对应于CSV文件中的行。如果我在一个线程中执行这些操作将会很长。
我想创建1,000个线程来执行i)从CSV文件中读取一行,ii)创建一个HTTP请求,其主体包含读取行的内容,以及iii)发送HTTP请求并接收响应。
通过这种方式,我需要将CSV文件拆分为1,000个块,并且这些块之间应该没有重叠的行。
这种分裂程序的最佳方法是什么?
答案 0 :(得分:10)
同时在多个位置读取单个文件不会让你走得更快(但它可能会大大减慢你的速度)。
不是从多个线程读取文件,而是从单个线程读取文件,并并行化这些行的处理。单线应该逐行读取CSV,并将每一行放入队列中。然后,多个工作线程应从队列中获取下一行,解析它,转换为请求,并根据需要同时处理请求。然后,通过单个线程完成工作的拆分,确保没有缺失的线或重叠。
答案 1 :(得分:5)
您可以拥有一个读取CSV行的线程并构建一个读取的行列表。当达到某个极限时,例如将100行传递给固定大小的线程池以作为请求发送。
我怀疑除非您的服务器有1000个核心,否则您可能会发现使用10-100个并发请求的速度更快。
答案 2 :(得分:2)
通过构建CSV
的对象并将其传递给{{{} Thread
,一旦您获得该行,将该行委托给池中可用的Runnable Task
之一,就可以在单个线程中读取Executors's
文件1}} submit()
,将异步执行。
public static void main(String[] args) throws IOException {
String fName = "C:\\Amit\\abc.csv";
String thisLine;
FileInputStream fis = new FileInputStream(fName);
DataInputStream myInput = new DataInputStream(fis);
ExecutorService pool=Executors.newFixedThreadPool(1000);
int count = 0; // Concurrent request to Server barrier
while ((thisLine = myInput.readLine()) != null) {
if (count > 150) {
try {
Thread.sleep(100);
count = 0;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
pool.submit(new MyTask(thisLine));
count++;
}
}
}
这是你的任务:
class MyTask implements Runnable {
private String lLine;
public MyTask(String line) {
this.lLine=line;
}
public void run() {
// 1) Create Request lLine
// 2) send the HTTP request out and receive response
}
}
答案 3 :(得分:1)
让一个线程逐行读取文件并读取每一行,将任务发布到ExecutorService
以对每个执行HTTP请求。
从多个线程读取文件不起作用,因为为了读取n
行,您必须首先阅读所有其他行。 (如果您的文件包含固定宽度记录,但理论上可以使用,但CSV不是固定宽度格式。)
答案 4 :(得分:1)
如果您希望通过同一操作解压缩和解析,请查看https://github.com/skjolber/unzip-csv。
答案 5 :(得分:0)