簡體   English   中英

使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM