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

これは明らかに学術的な演習であるため、executor スレッド プールを使用するという要件を考慮して、この問題にどのように対処するかについて概要を説明します。

まず、問題を分析し、互いに独立して実行できる反復可能な作業単位に分割する必要があります。この場合、作業の基本単位は、単一のファイルシステム ディレクトリを処理することです。ディレクトリを処理するたびに、次のことを行います。

  • 各ディレクトリ エントリを調べます。
  • ディレクトリ エントリが通常のファイルの場合は、リストに追加します。
  • ディレクトリ エントリがサブディレクトリの場合は、サブミットして処理します。

Runnable次に、この基本的な作業単位の処理をカプセル化するための実装を作成する必要があります。作成するクラスの各インスタンスには、少なくとも次の情報が必要です。

  • 処理するFileディレクトリを表す 。
  • すべてのワーカー間で共有され、ファイルを追加するためのリスト (他の人が指摘しているように、ArrayListこれには適したデータ構造ではありません)。
  • サブディレクトリのタスクを送信するための executor サービスへの参照。

最後に、最上位ディレクトリを処理するワーカーを作成する必要があります。エグゼキュータ サービスに送信します。そして、すべてのワーカーが処理を完了するまで待ちます。この最後の部分が最も難しいかもしれません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 に答える