簡體   English   中英

多線程,讀取多個文件並寫入新文件

[英]Multithreading, Read multiple files and write to new Files

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test6 implements Runnable {

    private File file;
    private int totalNumberOfFiles = 0;
    private static int nextFile = -1;
    private static ArrayList<String> allFilesArrayList = new ArrayList<String>();
    private static ExecutorService executorService = null;

    public Test6(File file) {
        this.file = file;
    }

    private String readFileToString(String fileAddress) {
        FileInputStream stream = null;
        MappedByteBuffer bb = null;
        String stringFromFile = "";
        try {
            stream = new FileInputStream(new File(fileAddress));
            FileChannel fc = stream.getChannel();
            bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
            /* Instead of using default, pass in a decoder. */
            stringFromFile = Charset.defaultCharset().decode(bb).toString();
        } catch (IOException e) {
            System.out.println("readFileToString IOException");
            e.printStackTrace();
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
                System.out.println("readFileToString IOException");
                e.printStackTrace();
            }
        }
        return stringFromFile;
    }

    private void toFile(String message, String fileName) {
        try {
            FileWriter fstream = new FileWriter("C:/Users/Nomi/Desktop/Workspace2/Test6/TestWritten/" + fileName);
            System.out.println("printing to file: ".concat(fileName));
            BufferedWriter out = new BufferedWriter(fstream);
            out.write(message);
            out.close();
        } catch (Exception e) {
            System.out.println("toFile() Exception");
            System.err.println("Error: " + e.getMessage());
        }
    }

//  private void listFilesForFolder(final File fileOrFolder) {
//      String temp = "";
//      if (fileOrFolder.isDirectory()) {
//          for (final File fileEntry : fileOrFolder.listFiles()) {
//              if (fileEntry.isFile()) {
//                  temp = fileEntry.getName();
//                  toFile(readFileToString(temp), "Copy".concat(temp));
//              }
//          }
//      }
//      if (fileOrFolder.isFile()) {
//          temp = fileOrFolder.getName();
//          toFile(readFileToString(temp), "Copy".concat(temp));
//      }
//  }

    public void getAllFilesInArrayList(final File fileOrFolder) {
        String temp = "";
        System.out.println("getAllFilesInArrayList fileOrFolder.getAbsolutePath()" + fileOrFolder.getAbsolutePath());
        if (fileOrFolder.isDirectory()) {
            for (final File fileEntry : fileOrFolder.listFiles()) {
                if (fileEntry.isFile()) {
                    temp = fileEntry.getAbsolutePath();
                    allFilesArrayList.add(temp);
                }
            }
        }
        if (fileOrFolder.isFile()) {
            temp = fileOrFolder.getAbsolutePath();
            allFilesArrayList.add(temp);
        }
        totalNumberOfFiles = allFilesArrayList.size();
        for (int i = 0; i < allFilesArrayList.size(); i++) {
            System.out.println("getAllFilesInArrayList path: " + allFilesArrayList.get(i));
        }
    }

    public synchronized String getNextFile() {
        nextFile++;
        if (nextFile < allFilesArrayList.size()) {
//          File tempFile = new File(allFilesArrayList.get(nextFile));
            return allFilesArrayList.get(nextFile);
        } else {
            return null;
        }
    }

    @Override
    public void run() {
        getAllFilesInArrayList(file);
        executorService = Executors.newFixedThreadPool(allFilesArrayList.size());
        while(nextFile < totalNumberOfFiles)
        {
            String tempGetFile = getNextFile();
            File tempFile = new File(allFilesArrayList.get(nextFile));
            toFile(readFileToString(tempFile.getAbsolutePath()), "Copy".concat(tempFile.getName()));
        }
    }

    public static void main(String[] args) {
        Test6 test6 = new Test6(new File("C:/Users/Nomi/Desktop/Workspace2/Test6/Test Files/"));
        Thread thread = new Thread(test6);
        thread.start();
//      executorService.execute(test6);
//      test6.listFilesForFolder(new File("C:/Users/Nomi/Desktop/Workspace2/Test6/"));
    }
}

程序正在按預期進行。 它進入文件夾,獲取文件,將其讀取為字符串,然后將內容寫入新文件。 我想做這個多線程。 如果該文件夾有N個文件,則需要N個線程。 另外,如果可能,我想使用執行程序框架。 我在想可以遵循以下方法:

public synchronized void getAllFilesInArrayList() {
        return nextFile;
    }

因此,每個新線程都可以選擇下一個文件。 謝謝您的幫助。

錯誤:

Exception in thread "Thread-0" java.lang.IllegalArgumentException
    at java.util.concurrent.ThreadPoolExecutor.<init>(ThreadPoolExecutor.java:589)
    at java.util.concurrent.ThreadPoolExecutor.<init>(ThreadPoolExecutor.java:480)
    at java.util.concurrent.Executors.newFixedThreadPool(Executors.java:59)
    at Test6.run(Test6.java:112)
    at java.lang.Thread.run(Thread.java:662)

首先,您解決問題的方法將導致同步和競態條件方面的擔憂超出所需的范圍。 一個防止線程競速的簡單策略是:

1)讓調度程序線程讀取目錄中的所有文件名。

2)對於每個文件,使調度程序線程產生一個工作線程並傳遞文件引用

3)讓工作線程處理文件

4)確保您的輸出文件名具有合理的命名約定,以免線程被彼此覆蓋。

至於使用執行程序,ThreadPoolExecutor可能會很好地工作。 看看Javadoc: http : //docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html

暫無
暫無

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

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