2013-08-19 29 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文件
相關問題