2

我需要ArrayList从某个位置序列化为所有绝对文件路径。我想用FixedThreadPoolfrom做到这一点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

4

3 回答 3

2

由于这显然是一个学术练习,我将概述我将如何处理这个问题,因为您需要使用执行程序线程池。

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

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

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

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

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

于 2012-12-21T17:01:42.430 回答
1

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

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

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

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

于 2012-12-21T16:27:33.857 回答
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);
}

就这样。

于 2012-12-21T16:31:58.153 回答