Java File方法" canWrite()"可以支持锁定吗?
我有一个Java应用程序,该程序监视文件夹中是否有传入的XML文件。当检测到新文件时,我需要测试该文件当前未更新并且已关闭。我的想法是使用File.canWrite()对此进行测试。这样做有什么问题吗?这是测试文件已完全写入的好方法吗?
我提出的其他想法是:
- 解析传入的XML文件并测试是否存在结束标记。
- 检查EoF字符。
我只是不确定这些方法中的任何一种是否可以处理所有情况。
解决方案
不可以,canWrite不适合此目的。通常,即使正在写入其他进程,该文件也是可写的。
我们需要更高级别的协议来协调锁定。如果我们打算在单个平台上使用此代码,则可以使用NIO的FileLock工具。但是请仔细阅读文档,并注意在许多平台上,该锁仅是建议性的。
另一种方法是让一个进程使用进程无法识别的名称来写入文件,然后在写入完成后将文件重命名为可识别的名称。在大多数平台上,如果源和目标是相同的文件系统卷,则重命名操作是原子的。名称更改可能会使用其他文件扩展名,甚至可能将文件从一个目录移动到另一个目录(在同一卷上)。
因为在这种情况下,我们只使用XML,所以寻找一个close标签是可行的,但这并不是万无一失的,如果在最终标记之后有注释,或者是作者还是根本没有写出有效的XML?
寻找EOF将不起作用。即使编写者刚刚打开文件但还没有编写任何内容,也始终会有一个EOF。如果不是这样,最简单的方法是允许读者在文件显示后立即开始解析;它只会阻塞直到作者关闭文件。但是文件系统不能以这种方式工作。每个文件都有一个结尾,即使当前有某些进程正在移动它。
据我所知,目前还无法判断其他进程当前是否具有来自Java的文件的打开句柄。一种选择是使用来自新io的FileLock类。并非在所有平台上都支持此功能,但是如果文件是本地文件,并且编写文件的过程可以配合使用,则此方法应适用于所有支持锁的平台。
此外,如果我们先进行检查然后再进行写操作,则说明我们处于竞争状态。状态可以在检查和写入之间改变。有时最好尝试做我们想做的事情,并优雅地处理错误。可能是一种n尝试重试机制,具有增加的后备延迟时间。
或者重新定义测试。在这种情况下,我们也许可以测试文件大小在处理之前一段时间没有变化。
另一个选择是将代码分成两部分,我们可能有另一个线程(也许是石英任务)负责将已完成的文件移动到主代码处理的其他目录中。
如果同时控制读取器和写入器,则潜在的锁定技术将是为读取和写入过程的持续时间创建一个锁定目录(通常是原子操作)。如果采用这种方法,则必须管理导致"挂起"的锁定目录的进程的潜在故障。
正如Cheekysoft提到的,文件不是原子的,不适用于锁定。
如果我们不控制编写器-例如,如果它是由FTP守护程序产生的-那么重命名技术或者时间跨度延迟技术是最佳选择。
在Windows中似乎起作用的一件事是
创建一个表示要讨论的文件的File()对象(使用具有完整文件名的构造函数)
以相同的方式创建另一个相同的文件对象。
尝试firstFile.renameTo(secondFile)
这个虚拟的重命名练习似乎可以成功打开未打开供另一个应用程序编辑的文件(我已使用Word测试),但如果打开则失败。
由于nw filename =旧文件名,因此它不会创建任何其他工作。