以下是我的情况:我正在使用IOUtils
来复制文件。我接下来要做的是向另一个程序发送一条JSON消息,说“你可以下载副本”。问题是大约25%的时间其他程序收到错误说“收到意外的EOF下载工件”。
每次发生此错误时,如果我再次手动尝试,则不会发生错误。我的理论是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版(最终版)。
答案 0 :(得分:3)
您当前的代码仅确保将文件内容传递给操作系统进行写入;它并不能保证它实际写入磁盘。
为了确保文件实际写入磁盘,您可以在sync()
上致电FileDescriptor
:
fileOutputStream.flush();
fileOutputStream.getFD().sync();