-1
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)
4

1 回答 1

2

首先,您解决问题的方法将导致更多的同步和竞争条件担忧,而不是看起来必要的。一个简单的策略来防止你的线程竞争是这样的:

1) 让调度程序线程读取目录中的所有文件名。

2) For each file, have the dispatcher thread spawn a worker thread and hand off the file reference

3) Have the worker thread process the file

4) Make sure you have some sane naming convention for your output file names so that you don't get threads overwriting each other.

As for using an executor, a ThreadPoolExecutor would probably work well. Go take a look at the javadoc: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html

于 2012-12-21T02:50:45.377 回答