2013-07-03 88 views
3

這是我的情況:我使用IOUtils來複制文件。接下來我要做的就是發送一條JSON消息給另一個程序,說「你可以下載副本」。問題是大約25%的時間其他程序得到錯誤說「收到意外的EOF下載神器」。IOUtils.copy是否阻止寫入完成?

每次發生此錯誤時,如果手動再次嘗試,則不會發生該錯誤。我的理論是,IOUtils.copy不會阻塞,操作系統仍在將文件寫入FS,而另一個程序嘗試下載它。有沒有辦法強制IOUtils.copy或其他功能相當的代碼阻塞,直到操作系統完成寫入文件?或者我的理論不正確?這裏是我使用的代碼:

private boolean archiveArtifact(String archivePath, String deployId, Artifact artifact) { 
    InputStream inputStream = null; 
    FileOutputStream fileOutputStream = null; 
    boolean successful = true; 

    try { 
     File archiveDir = new File(archivePath); 
     File deployDir = new File(archiveDir, deployId); 

     if (!deployDir.exists()) { 
      deployDir.mkdirs(); 
     } 

     URLConnection connection = new URL(artifact.getJenkinsUrl()).openConnection(); 
     inputStream = connection.getInputStream(); 
     File output = new File(deployDir, artifact.getFileName()); 
     fileOutputStream = new FileOutputStream(output); 
     IOUtils.copy(inputStream, fileOutputStream); 
    } catch (IOException e) { 
     successful = false; 
     logger.error(e.getMessage(), e); 
    } finally { 
     try { 
      if (fileOutputStream != null) { 
       fileOutputStream.close(); 
      } 
     } catch (IOException e) { 
      successful = false; 
      logger.error(e.getMessage(), e); 
     } 

     try { 
      if (inputStream != null) { 
       inputStream.close(); 
      } 
     } catch (IOException e) { 
      successful = false; 
      logger.error(e.getMessage(), e); 
     } 
    } 

    return successful; 
} 

可能值得注意的是,我將它複製到NFS。請記住我並不知道有關NFS的任何信息。這是CentOS 5.9(最終版)。

回答

3

您目前的代碼只能確保將文件內容傳遞給操作系統進行寫入;它並不保證它實際寫入磁盤。

要確定該文件實際寫入磁盤,你可以在FileDescriptor呼籲sync()

fileOutputStream.flush(); 
fileOutputStream.getFD().sync(); 
+0

好,謝謝,我會嘗試一下,看看問題是否會消失。 –