2015-09-28 24 views
0

我想從網絡共享中使用scala代碼將大量文件(數百萬)複製到我的電腦中。我正在使用的方法是listfiles()來獲取文件夾中的所有文件,並通過列表來複制我想要的文件。它適用於小型號。的文件,但作爲沒有。的文件變成了數百萬的文件,從而引發內存溢出異常。有沒有其他方法可以用來遍歷文件,並選擇我想要複製的文件,而不會在java或scala中引發此異常。當我搜索這個問題時,我看到了簡單的文件訪問者,任何人都可以幫助我如何使用它從文件夾中篩選後複製文件。使用Scala代碼從Windows共享文件夾中複製大量日誌文件

def copyRenamedFiles(directoryName: String, trackerFileName: String, loggerFileName: String): Unit = { 
    val destFolder = "D:\\data\\" 
    val logWriter = Logger.getLogger("UploadServiceLog") 
    logWriter.setUseParentHandlers(false) 
    val hashMapForFileTracking = FileTracking.getTracker(trackerFileName, logWriter) 
    try { 
     println("Inside try block") 
     //LogFile Informations........................ 
     val fh = new FileHandler(loggerFileName) 
     logWriter.addHandler(fh) 
     val formatter = new SimpleFormatter() 
     fh.setFormatter(formatter) 
     //............................................ 
     if (!new File(directoryName).exists()) { 
     throw new FileNotFoundException("Specified Path is not found") 
     } 
     val rootFile = new File(directoryName) 
     println(rootFile.isDirectory) 
     if (rootFile.isDirectory) { 
     // println("Inside rootfolder\n"+rootFile.listFiles().length) 
     rootFile.listFiles().foreach { 
      machineFile => if (machineFile.isDirectory) { 

      // My filter logic and copying goes here 

} 

但rootFile.listFiles(rootFile.list也)本身會拋出內存超出限制的異常。文件夾層次結構是根文件夾 - >許多機器文件夾 - >每個機器文件夾包含許多dailylogfolders - >每個每日文件夾包含一個日誌文件。

+0

您能否提供您正在嘗試的代碼示例? –

+0

通常使用'rsync'(Linux工具,但可能在Windows上)或類似的;與壓縮等。在你的情況下,檢查是否一切都關閉了,也有例外情況。 listFiles可能會返回一個空文件[]。需要良好的錯誤報告(正在使用的文件,動態文件)。 –

+0

@ Conrad.Dean我添加了代碼。你能看到嗎? – user5147250

回答

2

如果你的問題是文件數組太大而不適合內存,你應該考慮如何獲得一些延遲評估的東西,一個Stream或Iterator。快速搜索,我發現這一點:

http://www.adam-bien.com/roller/abien/entry/listing_directory_contents_with_jdk

這是從鏈接複製上述

public static List<String> fileList(String directory) { 
    List<String> fileNames = new ArrayList<>(); 
    try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(directory))) { 
     for (Path path : directoryStream) { 
      fileNames.add(path.toString()); 
     } 
    } catch (IOException ex) {} 
    return fileNames; 
} 

它是新的Java IO庫的一部分,顯示瞭如何創建一個DirectoryStream不應該把你的整個記憶。

+0

Łukasz我早些時候已經嘗試過這種方法。其實我想要scala中的代碼。所以當我嘗試這個我不能完成,因爲我不能應用過濾器的目錄流。現在注意到我可以在流上應用迭代器。所以我認爲它會奏效。感謝您的時間 – user5147250

+0

DirectoryStream實現了java Iterable,您可以將其轉換爲scala Iterable並擁有所有方法。 –

+0

是的,可以使用迭代器完成它。再次感謝您的幫助 – user5147250

相關問題