2015-01-27 38 views
2

我有一臺服務器,它從Windows共享目錄中讀取文本文件列表,並在其開始接受用戶消息之前將其保存到數據庫。該服務器將一次在多臺機器上運行。並行讀取Windows共享目錄中的文件

我看到,當我在多臺機器上運行服務器時,開始處理這些文件的服務器首先處理所有文件,其他服務器繼續等待訪問該目錄中的文件。

我的代碼做到這一點 - (不能由於安全策略郵編)

  1. 獲取列表中的所有文件的共享目錄。
  2. 您可以按照修改日期(其保存的時間序列數據)
  3. 雖然(真),直到更多的文件在目錄中存在
  4. 獲取列表中的第一個文件,並將其移動到InProgess文件夾和讀取
  5. 將內容保存到數據庫。
  6. 將文件移到歸檔目錄。
  7. 處理下一個文件。

我看到,當我在兩臺不同的機器上運行相同的程序時,其中一臺機器首先獲取文件並將其全部加載。另一個人一直在等待處理這些文件,如果它找到了句柄,則它們已經被處理。所以它繼續前進。

我的目標是在兩臺或多臺機器上運行並行處理所有文件並更快完成的過程。現在我正在用磁盤上的500個文件進行測試,但是我可以在任何時候在磁盤上有更多的文件。

僞 -

if(files exist on disk){ 
    LOGGER.info("Files exist on disk. Lets process them up first...."); 
    while (true) { 
     File dir = new File(directory); 
     List<File> fileList = new LinkedList<File>(Arrays.asList(dir.listFiles((FileFilter)FileFileFilter.FILE))); 
     LOGGER.info("No of files in this process: "+ sortedFileList.size()); 
     if (fileList.size() > 0) { 
      Collections.sort(fileList, new Server().new FileComparator()); 
      File file = fileList.get(0); 

      //If I cannot rename the file in the same directory, the file maybe open and I move to the next file  
      if(!file.renameTo(file.getAbsoluteFile())) { 
       LOGGER.info("Read next file..."); 
       continue; 
      } 
      LOGGER.info("Get file handle..."); 
      if (file.exists()) { 
       File inprogressFile = new File(dataDirName + FileBackupOnDisk.INPROGRESS + fileName); 
       saveToDB(inprogressFile); 
       if (savedToDB) 
        if(inprogressFile.renameTo(new File(dataDirName+ARCHIVE+fileName))) 
        LOGGER.info("Moved file to archive - " + fileName); 
       else   
        LOGGER.error("Move file " + fileName + " to failed directory!"); 
      } 
     } 
    } 
} 

這是我的文件比較的代碼。這不能打開文件 -

final Map<File, Long> staticLastModifiedTimes = new HashMap<File,Long>(); 
    for(final File f : sortedFileList) {          
     staticLastModifiedTimes.put(f, f.lastModified()); 
    } 

    Collections.sort(sortedFileList, new Comparator<File>() { 
     @Override 
     public int compare(final File f1, final File f2) { 
      return   
    staticLastModifiedTimes.get(f1).compareTo(staticLastModifiedTimes.get(f2)); 
    } 
}); 

如何確保在不同的機器上運行我的兩個服務器/多臺服務器都能夠訪問直接並聯共享。現在看起來第二個進程發現文件存在於dir中,但是一直等待獲取文件句柄。

讓我知道如果有人以前做過這個,怎麼做?

+0

問題是,當代碼無法打開文件時,它會一直嘗試下去,直到文件已經被處理,這當然不會發生。代碼需要跳過任何無法打開的文件,直到找到可以打開的文件。 – 2015-01-27 02:00:40

+0

它不會超出第二個啓動過程中的分類點。即使我評論這行'code' Collections.sort(fileList,new Server())。新的FileComparator());'代碼',它從不執行後面的行。如果file.exists()不是真的,我可以放入'code'繼續;'code'部分,但它永遠不會跨越那個點。 – PS5 2015-01-27 16:09:41

+0

我想你打開'FileComparator'中的文件?無論如何,你的邏輯中肯定存在一個錯誤。 Windows不會阻止多臺機器同時從同一目錄中讀取文件。如果你可以在你的代碼中確定它正在等待文件句柄的地方,這可能會有所幫助,因爲它不應該試圖在那個時候打開一個文件。 (也許無論您用來檢索修改日期的Java API是否會打開文件?) – 2015-01-27 23:10:48

回答

0

我發現我上面的解決方案工作得很好!!!! 它只是從我的eclipse中運行一個實例與另一個從網絡中的m/c運行導致此延遲問題。 如果我在同一個網絡中運行2臺機器的程序,它工作正常。只是我的電腦速度較慢。這兩個實例在讀取文件時都能讀取文件。 謝謝大家的幫助。

相關問題