2016-10-04 630 views
2

此代碼:FileAlreadyExistsException拋出,並且重寫文件

File tmpFile = File.createTempFile(PREFIX_TMP, null, new File(reportPath)); 
     logger.debug("The report will be saved in the temporary file '{}'", tmpFile.getName()); 

     reportWriter.write(tmpFile, report); 

     Calendar calendar = Calendar.getInstance(); 

     boolean isFileMoved = false; 
     while (!isFileMoved) { 
      String reportName = String.format(report.getName(), calendar.getTime()); 
      File reportFile = new File(reportPath, reportName); 

      try { 
       Files.move(tmpFile.toPath(), reportFile.toPath()); 
       isFileMoved = true; 

       logger.info("The temporary file '{}' is renamed to '{}'", tmpFile.getName(), reportFile.getName()); 
      } catch (FileAlreadyExistsException e) { 
       logger.warn("The file '{}' already exists in the folder '{}': adding a second to generation time", 
         reportName, reportPath); 
      } 

      calendar.add(Calendar.SECOND, 1); 
     } 

生成以下,是不可能的,登錄的語句:

2016年10月4日10:35:11674 [WARN] [ _Executor-1] abcMyGenerator - 的 文件 'myFile_01092016103511.csv' 已經存在的文件夾 '/ MYDIR' 中:添加第二代時間

2016年10月4日10:35:11677 [WARN ] [_Executor-3] abcMyGenerator - 的 文件 'myFile_01092016103511.csv' 已經存在的文件夾 '/ MYDIR' 中:添加第二代時間

2016年10月4日10:35:11677 [INFO ] [_Executor-1] abcMyGenerator - 的 臨時文件 'tmp2103892505851032137.tmp' 被重命名爲 'myFile_01092016103512.csv'

2016年10月4日10:35:11680 [INFO] [_Executor-3] ABC MyGenerator - 將 臨時文件'tmp6843688962754506611.tmp'更名爲 'myFile_01092016103512.csv'

Executor 3重寫該文件,即使它應該拋出FileAlreadyExistsException。

沒有拋出異常,並且文件的數據已被覆蓋。

回答

1

Executor 3覆蓋文件,即使它應該拋出FileAlreadyExistsException。

如果您希望Files.move(...)以原子方式操作,則需要使用ATOMIC_MOVE option。默認情況下,它首先測試目標是否存在,然後執行易受thread race conditions影響的移動。以下是javadocs for Files.move(...)

ATOMIC_MOVE - 將移動執行爲原子文件操作。如果文件系統不支持原子移動,則會引發異常。使用ATOMIC_MOVE,您可以將文件移動到目錄中,並確保任何正在監視目錄的進程訪問完整的文件。

如果你必須有FileAlreadyExistsException支持,那麼你將需要保護的動作與​​塊只允許一個線程在同一時間運行它。鑑於你在這個塊中正在做IO,​​應該沒有什麼性能損失。

0

Files.move使用Files.exists內部,狀態可以使用多線程時之間發生了變化英寸

相關問題