2013-08-19 65 views
0

我正在编写一个Java应用程序以获取文件的文件元数据并将其导出到csv文件。如果文件数量较少,该应用可以正常工作。但是,如果我在所有目录和子目录中提供一个拥有320000个文件的路径,它将永远占用。有什么方法可以在这里加快速度?Java - 获取具有百万个文件的目录中的文件的元数据

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()); 

    } 
} 

}

+3

这可能会更好[codereview](http://codereview.stackexchange.com)与您的代码包括在内。没有人能够在没有真正看到你的代码的情况下帮助提高性能(或者告诉你它是否可以改进)。 – Michelle

回答

1

许多文件系统是不是在处理与他们中的许多项目目录高效。你可以用代码来做很少的事来解决这个问题。您需要尝试将这些文件移动到多个目录中,以获得更好的速度。

缓慢的其他可能的原因是,您要么使用的数据结构,每个条目需要O(n)(导致O(n2)总运行时间),或者您的堆空间不足GC支配运行时)。

0

如果您使用的是Java 7,则可以使用Files walking tree intf来重写以检查文件系统问题是否是您的代码(也许您使用的数据结构性能较差,或者内存不足,程序运行速度变慢执行)

编辑:
此行

File[] listOfFiles = libSourcePath.listFiles(); 

将创建320K对象在存储器阵列,并且对于性能差(或的OutOfMemoryError)

的好方法10

和第二个问题:

FileWriter writer = new FileWriter(extractFile, true); 

你是开/关德CSV文件每次你需要编写一个文件元数据的时间!

你有作品就像一个方式:

  1. 打开CSV FileWriter的
  2. 使用Files walking tree intf 为Java7或 DirectoryWalker 对于以前的版本中递归地检查每个目录
  3. 每文件遇到greetree(prev。point)将文件元数据写入CSV(如果需要,请刷新CSV文件)
  4. 关闭CSV文件
相关问题