![](/img/trans.png)
[英]Read from one large file and write to many (tens, hundreds, or thousands) files in Java?
[英]Read from a large file and write to multiple files with java
我有一個 A.txt 文件,有 100,000,000 條記錄,從 1 到 100000000,每條記錄一行。 我要讀文件A,然后寫文件B和C,前提是偶數行寫文件B,奇數行寫文件C。要求讀寫時間必須小於40秒。 下面是我已有的代碼,但運行時間超過 50 秒。 有沒有人有任何其他解決方案來減少運行時間?
線程.java
import java.io.*;
import java.util.concurrent.LinkedBlockingQueue;
public class Threading implements Runnable {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
String file;
Boolean stop = false;
public Threading(String file) {
this.file = file;
}
public void addQueue(String row) {
queue.add();
}
public void Stop() {
stop = true;
}
public void run() {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
while(!stop) {
try {
String rơ = queue.take();
bw.while(row + "\n");
} catch (Exception e) {
e.printStackTrace();
}
}
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
線程創建.java
// 我使用 2 個線程寫入 2 個文件 B 和 C
import java.io.*;
import java.util.List;
public class ThreadCreate {
public void startThread(File file) {
Threading t1 = new Threading("B.txt");
Threading t1 = new Threading("B.txt");
Thread td1 = new Thread(t1);
Thread td1 = new Thread(t1);
td1.start();
td2.start();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
long start = System.currentTimeMillis();
while ((line = br.readLine()) != null) {
if (Integer.parseInt(line) % 2 == 0) {
t1.addQueue(line);
} else {
t2.addQueue(line);
}
}
t1.Stop();
t2.Stop();
br.close();
long end = System.currentTimeMillis();
System.out.println("Time to read file A and write file B, C: " + ((end - start)/1000) + "s");
} catch (Exception e) {
e.printStackTrace();
}
}
}
主要.java
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("A.txt");
//Write file B, C
ThreadCreate t = new ThreadCreate();
t.startThread(file);
}
}
你為什么要制作線程? 那只會減慢速度。 如果瓶頸是計算本身或操作的阻塞性質,則線程很有用,如果不是,它們只會造成傷害。 在這里,它不是:CPU 只是空閑(瓶頸將是磁盤),它阻塞的性質意味着多線程也無濟於事:告訴單個 SSD 並行寫入 2 船字節可能不會更快(只會更慢,因為它需要來回反彈)。 如果目標磁盤是一個旋轉磁盤,它會慢得多 - 寫頭不能更快地將自己克隆到 go,並且通過使其成為多線程,你會浪費大量時間來要求寫頭來回反彈在不同的寫入位置之間。
沒有什么可以立即讓我覺得可以顯着加速的了。
有時,將大量數據寫入磁盤僅需 50 秒。 如果不能接受,請購買更快的磁盤。
嘗試 memory 映射文件
byte[] buffer = "foo bar foo bar text\n".getBytes();
int number_of_lines = 100000000;
FileChannel file = new RandomAccessFile("writeFIle.txt", "rw").getChannel();
ByteBuffer wrBuf = file.map(FileChannel.MapMode.READ_WRITE, 0, buffer.length * number_of_lines);
for (int i = 0; i < number_of_lines; i++)
{
wrBuf.put(buffer);
}
file.close();
在我的電腦上(戴爾,I7 處理器,帶 SSD,32GB RAM)運行這段代碼需要半分鍾多一點的時間)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.