0

ディレクトリ内のファイルのファイル メタデータを取得し、それを csv ファイルにエクスポートする Java アプリを作成しています。ファイルの数が少ない場合、アプリは正常に動作します。しかし、すべてのディレクトリとサブディレクトリに320000個のファイルがあるパスをフィードすると、永遠にかかります。ここで物事をスピードアップする方法はありますか?

    private void extractDetailsCSV(File libSourcePath, String extractFile) throws ScraperException {

    log.info("Inside extract details csv");

    try{
        FileMetadataUtil fileUtil = new FileMetadataUtil();

        File[] listOfFiles = libSourcePath.listFiles();

        for(int i = 0; i < listOfFiles.length; i++) {

            if(listOfFiles[i].isDirectory()) {
                extractDetailsCSV(listOfFiles[i],extractFile);
            }

            if(listOfFiles[i].isFile()){

                ScraperOutputVO so = new ScraperOutputVO();

                Path path = Paths.get(listOfFiles[i].getAbsolutePath());

                so.setFilePath(listOfFiles[i].getParent());
                so.setFileName(listOfFiles[i].getName());

                so.setFileType(getFileType(listOfFiles[i].getAbsolutePath()));

                BasicFileAttributes basicAttribs = fileUtil.getBasicFileAttributes(path);
                if(basicAttribs != null) {
                    so.setDateCreated(basicAttribs.creationTime().toString().substring(0, 10) + " " + basicAttribs.creationTime().toString().substring(11, 16));
                    so.setDateLastModified(basicAttribs.lastModifiedTime().toString().substring(0, 10) + " " + basicAttribs.lastModifiedTime().toString().substring(11, 16));
                    so.setDateLastAccessed(basicAttribs.lastAccessTime().toString().substring(0, 10) + " " + basicAttribs.lastAccessTime().toString().substring(11, 16));
                }

                so.setFileSize(String.valueOf(listOfFiles[i].length()));
                so.setAuthors(fileUtil.getOwner(path));

                so.setFolderLink(listOfFiles[i].getAbsolutePath());
                writeCsvFileDtl(extractFile, so);

                so.setFileName(listOfFiles[i].getName());
                noOfFiles ++;
            }
        }
    } catch (Exception e) {
        log.error("IOException while setting up columns" + e.fillInStackTrace());
        throw new ScraperException("IOException while setting up columns" , e.fillInStackTrace());
    }

    log.info("Done extracting details to csv file");
}

public void writeCsvFileDtl(String extractFile, ScraperOutputVO scraperOutputVO) throws ScraperException {
    try {
        FileWriter writer = new FileWriter(extractFile, true);
        writer.append(scraperOutputVO.getFilePath());
        writer.append(',');
        writer.append(scraperOutputVO.getFileName());
        writer.append(',');
        writer.append(scraperOutputVO.getFileType());
        writer.append(',');
        writer.append(scraperOutputVO.getDateCreated());
        writer.append(',');
        writer.append(scraperOutputVO.getDateLastModified());
        writer.append(',');
        writer.append(scraperOutputVO.getDateLastAccessed());
        writer.append(',');
        writer.append(scraperOutputVO.getFileSize());
        writer.append(',');
        writer.append(scraperOutputVO.getAuthors());
        writer.append(',');
        writer.append(scraperOutputVO.getFolderLink());
        writer.append('\n');
        writer.flush();
        writer.close();
    } catch (IOException e) {
        log.info("IOException while writing to csv file" + e.fillInStackTrace());
        throw new ScraperException("IOException while writing to csv file" , e.fillInStackTrace());

    }
}

}

4

2 に答える 2

1

多くのファイルシステムは、非常に多くのエントリを含むディレクトリを効率的に処理できません。それを修正するためにコード単位でできることはほとんどありません。速度を上げるには、これらのファイルを複数のディレクトリに移動する必要があります。

速度低下のその他の考えられる理由としては、エントリごとに O(n) を使用するデータ構造を使用している (合計実行時間が O(n²) になる) か、ヒープ領域が不足している (GC が実行時間を支配する) ことが考えられます。 )。

于 2013-08-19T14:18:12.060 に答える
0

Java 7 を使用している場合は、ファイル ウォーキング ツリー intfを使用して書き直して、問題のファイル システムの問題がコードであるかどうかを確認できます (パフォーマンスの低いデータ構造を使用しているか、メモリが不足していて、実行中にプログラムが遅くなった可能性があります)。 )

編集:
この行

File[] listOfFiles = libSourcePath.listFiles();

メモリ内に 320k オブジェクトの配列を作成し、パフォーマンスの低下 (または OutOfmemoryError) に適した方法です。

そして2番目の問題:

FileWriter writer = new FileWriter(extractFile, true);

ファイルのメタデータを書き込む必要があるたびに、CSV ファイルを開いたり閉じたりします。

次のような方法で作業する必要があります。

  1. CSV fileWriter を開く
  2. Java7 の場合は ファイル ウォーキング ツリー intf 、以前のバージョンの場合はDirectoryWalker を使用して、すべてのディレクトリを再帰的に検査します。
  3. 再帰ダートツリー (前のポイント) 中に遭遇するすべてのファイルについて、ファイルのメタデータを CSV に書き込みます (必要に応じて CSV ファイルをフラッシュします)。
  4. CSV ファイルを閉じる
于 2013-08-19T14:24:23.803 に答える