0

我正在编写一个 Java 应用程序来获取目录中文件的文件元数据并将其导出到 csv 文件。如果文件数量较少,该应用程序可以正常工作。但是,如果我输入一个在所有目录和子目录中包含 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,您可以使用Files walk tree intf进行重写,以检查问题是否是您的代码的文件系统问题(可能您使用的数据结构性能不佳,或者您的内存不足并且程序在执行过程中变慢)

编辑:
这条线

File[] listOfFiles = libSourcePath.listFiles();

将在内存中创建一个包含 320k 对象的数组,并且是解决性能不佳(或 OutOfmemoryError)的好方法

第二个问题:

FileWriter writer = new FileWriter(extractFile, true);

每次需要写入文件元数据时,您都在打开/关闭 CSV 文件!

您必须以如下方式工作:

  1. 打开 CSV 文件编写器
  2. 使用Java7 的Files walk tree intf 或 以前版本的DirectoryWalker 以递归方式检查每个目录
  3. 对于递归脏树时遇到的每个文件(前一点),将文件元数据写入 CSV(如果需要,还可以刷新 CSV 文件)
  4. 关闭 CSV 文件
于 2013-08-19T14:24:23.803 回答