假设您有一个外部进程将文件写入某个目录,并且您有一个单独的进程定期尝试从该目录中读取文件.要避免的问题是读取另一个进程当前正在写出的文件,因此它将是不完整的.当前,读取的进程使用最小文件年龄计时器检查,因此它将忽略所有文件,除非它们的上次修改日期超过XX秒.
我想知道是否有更清洁的方法来解决这个问题.如果文件类型未知(可能是多种不同的格式),是否有一些可靠的方法来检查文件头中应该在文件中的字节数,以及文件中当前确认它们匹配的字节数?
感谢您的任何想法或想法!
Mic*_*ski 12
您可以使用外部标记文件.写入过程可以在开始创建文件XYZ之前创建文件XYZ.lock,并在XYZ完成后删除XYZ.lock.然后,读者可以很容易地知道,只有在相应的.lock文件不存在时才能认为文件是完整的.
Joh*_*lly 11
我过去这样做的方式是编写文件的进程写入"temp"文件,然后在文件写完后将文件移动到读取位置.
因此写入过程将写入info.txt.tmp.完成后,它会将文件重命名为info.txt.然后阅读过程只需要检查info.txt的存在- 它知道如果它存在,它已经完全写入.
或者,您可以让写入进程将info.txt写入另一个目录,如果您不喜欢使用奇怪的文件扩展名,则将其移动到读取目录.
我过去在 Windows 的这种情况下使用的一个简单解决方案是使用boolean File.renameTo(File) 并尝试将原始文件移动到单独的暂存文件夹:
boolean success = potentiallyIncompleteFile.renameTo(stagingAreaFile);
Run Code Online (Sandbox Code Playgroud)
如果success是false,则potentiallyIncompleteFile仍在写入。
我无法使用临时标记等,因为客户端通过密钥对SFTP上传文件.它们的尺寸可能非常大.
它相当hacky但我比较睡眠前后几秒钟的文件大小.
它显然不是理想的锁定线程,但在我们的情况下它只是作为后台系统进程运行所以似乎工作正常
private boolean isCompletelyWritten(File file) throws InterruptedException{
Long fileSizeBefore = file.length();
Thread.sleep(3000);
Long fileSizeAfter = file.length();
System.out.println("comparing file size " + fileSizeBefore + " with " + fileSizeAfter);
if (fileSizeBefore.equals(fileSizeAfter)) {
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
注意:如下所述,这可能不适用于Windows.这用于Linux环境.
| 归档时间: |
|
| 查看次数: |
17327 次 |
| 最近记录: |