2013-07-03 233 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

好,谢谢,我会尝试一下,看看问题是否会消失。 –