簡體   English   中英

將串行讀取多個文件轉換為並行讀取它們?

[英]Converting serially reading multiple files to reading them in parallel?

Java中的以下代碼一個接一個地讀取多個文件,直到這里運行良好 (這些文件是 JSON 並且在這一步它們被存儲在一個字符串/緩沖區中而無需解析。)

for (int fileIndex = 0; fileIndex < numberOfFiles; fileIndex++) {

        BufferedReader br = new BufferedReader(new FileReader("Files/file" + fileIndex + ".json"));
        try {
            StringBuilder sb = new StringBuilder();
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                sb.append(System.lineSeparator());
                line = br.readLine();
            }
            String contentJSON = sb.toString();
        } finally {
            br.close();
        }
    }

如何使用Threads並行讀取這些文件?

我無法將多線程與上述代碼匹配,並且每次都會出錯。

編輯:我測試了用戶@MadProgrammer的答案,並收到以下錯誤消息:

SEVERE: null
java.util.concurrent.ExecutionException: java.io.FileNotFoundException: Files\file0.json (The system cannot find the path specified)
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at com.Test.<init>(Test.java:24)
    at com.MainDefaultComponent.main(MainDefaultComponent.java:507)
Caused by: java.io.FileNotFoundException: Files\file0.json (The system cannot find the path specified)
    at java.base/java.io.FileInputStream.open0(Native Method)
    at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111)
    at java.base/java.io.FileReader.<init>(FileReader.java:60)
    at com.Test$ReadWorker.call(Test.java:44)
    at com.Test$ReadWorker.call(Test.java:34)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833) 

我沒有直接測試過這段代碼(因為我沒有一堆文件要讀取),但基本的想法是做類似......

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        try {
            int numberOfFiles = 10;
            ExecutorService service = Executors.newFixedThreadPool(10);
            List<ReadWorker> workers = new ArrayList<>(numberOfFiles);
            for (int fileIndex = 0; fileIndex < numberOfFiles; fileIndex++) {
                workers.add(new ReadWorker(fileIndex));
            }
            List<Future<String>> results = service.invokeAll(workers);
            for (Future<String> result : results) {
                try {
                    String value = result.get();
                } catch (ExecutionException ex) {
                    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public class ReadWorker implements Callable<String> {

        private int fileIndex;

        public ReadWorker(int fileIndex) {
            this.fileIndex = fileIndex;
        }

        @Override
        public String call() throws Exception {
            try (BufferedReader br = new BufferedReader(new FileReader("Files/file" + fileIndex + ".json"))) {
                StringBuilder sb = new StringBuilder();
                String line = br.readLine();

                while (line != null) {
                    sb.append(line);
                    sb.append(System.lineSeparator());
                    line = br.readLine();
                }
                return sb.toString();
            }
        }

    }
}

這基本上會執行一系列Callable並等待它們全部完成,此時您可以讀取結果(或錯誤)

有關更多詳細信息,請參閱Executors跟蹤

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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