线程池问题 - 收集文件

时间:2012-12-21 16:07:01

标签: java threadpool executorservice

我需要从一个位置序列化到ArrayList所有绝对文件路径。我希望使用FixedThreadPool中的ExecutorService进行此操作。

示例 - location: c:/folder1; folder1里面有更多的文件夹,都有文件。我希望每次我找到一个文件夹搜索他们的文件以添加到ArrayList。

public class FilePoolThreads extends Thread {

    File fich;
    private ArrayList al1;

    public FilePoolThreads(File fi, ArrayList<String> al) {
        this.fich = fi;
        this.al1 = al;
    }

    public void run() {
        FileColector fc = new FileColector();
        File[] listaFicheiros = fich.listFiles();

        for (int i = 0; i < listaFicheiros.length; i++) {
            if (listaFicheiros[i].isFile()) {
                al1.add(listaFicheiros[i].getAbsolutePath());
            }
        }
    }
}

我开始收集文件的类:

public class FileColector {

private ArrayList<String> list1 = new ArrayList<>();

public static ArrayList<String> search(File fich,ArrayList<String> list1) {


    int n1 = 1;
    ExecutorService executor = Executors.newFixedThreadPool(n1);
    do {
        //  FilePoolThreads[] threads=new FilePoolThreads[10];
        FilePoolThreads mt = new FilePoolThreads(fich, list1);

        executor.execute(mt);

    } while (fich.isDirectory());

    executor.shutdown();

    return list1;
}

我的代码运行不正常,我认为我有一些逻辑失败,我需要有人帮我修复它,我怎样才能返回ArrayList?我必须先使用getInputStream,然后使用getOutputStream

3 个答案:

答案 0 :(得分:2)

由于这显然是一个学术练习,我将概述如何使用执行程序线程池来解决此问题。

首先,您需要分析问题并将其分解为可重复的工作单元,这些工作单元可以彼此独立地完成。在这种情况下,基本工作单元正在处理单个文件系统目录。每次处理目录时,您都会:

  • 检查每个目录条目。
  • 如果目录条目是常规文件,请将其添加到列表中。
  • 如果目录条目是子目录,请提交以进行处理。

接下来,您需要创建Runnable的实现来封装此基本工作单元的处理。您创建的每个类的实例至少需要以下信息:

  • 表示要处理的目录的File
  • 在所有工作人员之间共享的列表,用于添加文件(并且正如其他人所指出的那样,ArrayList不适合这种情况的数据结构。)
  • 对执行程序服务的引用,用于提交子目录的任务。

最后,您需要为要处理的顶级目录创建一个worker;将其提交给遗嘱执行人服务;然后等到所有工人都完成处理。最后一部分可能是最棘手的 - 您可能需要使用传递给每个工作人员的AtomicInteger来保持运行计数,以跟踪当前正在处理的工作人员数量。

答案 1 :(得分:1)

不要扩展Thread以将您的任务传递给exectuor。改为实施Runnable

或者,实现Callable,它可以在完成执行时返回结果。

然后,您可以将任务传递给ExecutorService.submit(),并在完成每个任务的计算结果后返回Futureget()

请注意,您可能希望递归访问子目录,因此在添加文件之前需要找到目录文件输出并为目录创建新任务

答案 2 :(得分:1)

这里不需要线程,并且您有几个与尝试使用线程相关的错误。我的建议是忘记线程并解决你真正的问题,这可以通过commons-io FileUtils之类的东西非常简单地完成:

Iterator<File> files = FileUtils.iterateFiles(directoryToScan, FileFileFilter.FILE, TrueFileFilter.INSTANCE);
List<String> paths = new ArrayList<String>();
for (File file : files) {
    paths.add(file.getAbsolutePath);
}

这就是全部。