2014-02-18 110 views
1

我有一個將PDF文件(子文件夾)複製到目標文件夾的小應用程序。但它工作得很慢,我想優化它。你可以幫我嗎?Java遞歸文件複製優化

代碼:

public void pdfFolderCopy(File src, File dest) 
      throws IOException { 
     if (src.isDirectory()) { 
      if (!dest.exists()) { 
       dest.mkdir(); 
      } 
      String files[] = src.list(); 
      for (String file : files) { 
       File srcFile = new File(src, file); 
       File destFile = new File(dest, file); 
       pdfFolderCopy(srcFile, destFile); 
      } 
     } else { 
      if (!dest.exists()) { 
       System.out.println("Copying: " + src); 
       //Use the Apache IO copyFile method: 
       FileUtils.copyFile(src, dest); 
      } 
     } 
    } 

它是運行約一分半鐘,如果每一個文件都已經存在。大約5分鐘,如果我們需要複製約500個文件。

+0

看不出爲什麼這應該如此緩慢。嘗試記錄一些時間 –

+0

我認爲這也取決於文件的大小以及它們多大? –

+0

大約有15000個文件,包含100K fileszie。 – Roberto

回答

1

我會盡量簡單地調用過程做

/bin/cp -R -n src dest 

其中-R意味着遞歸和-n表示不覆蓋。操作系統很有可能比你更快地完成這個任務。不知道Windows或其他操作系統的相應命令是什麼。

爲此,您只需要

new ProcessBuilder() 
.command("/bin/cp", "-R", "-n", src.toString(), dest.toString()) 
.start(); 

如果你想這樣做在Java中,我想嘗試一些細微的變化:

  • dest.mkdir()沒有任何檢查工作,並可能會有點更快
  • listFiles可能比手動編寫它們更快(可能不相關)
  • 一旦您創建了dest文件夾自己,你並不需要檢查是否有任何預先存在的文件有

我想,多線程可能會導致一個不錯的加速:讓主線程創建複製工作,並提交給一些執行人(有一些4-8線程)。

請注意,此類多線程寫入可能導致更高的磁盤碎片,但我不在乎。如果必須,我會創建文件重做作業,讓它們返回文件內容(n * 100 KB沒有任何內容),並使用單個寫入器線程。

2

代碼中唯一真正耗時的任務是FileUtils.copyFile()。根據要複製的文件數量和大小,必要的時間將會增加。

關於您的代碼,我建議提取dest目錄的檢查,因爲它不應在複製過程中更改。檢查並創建dest目錄,然後開始pdfFolderCopy

+0

你的最後一段對我來說毫無意義。測試'dest.exists()'將測試目錄的存在,並且不會被複制。 – maaartinus

+0

@maaartinus是的,你是對的。我已將其刪除。 – wolfrevo