具有读写模式的 RandomAccessFile 过滤器在 linux 环境下不起作用
Posted
技术标签:
【中文标题】具有读写模式的 RandomAccessFile 过滤器在 linux 环境下不起作用【英文标题】:RandomAccessFile filter with read write mode does not work on linux environment 【发布时间】:2018-11-27 14:49:23 【问题描述】:我需要帮助来解决有关过滤未完全编写的文件的问题,因为在这种情况下我遇到了异常。
场景是:我有一个程序从队列中获取文件并将其放在服务器上的某个位置,另一个程序从该位置读取这些文件,这两个程序都在连续运行,并且消费者不断轮询以检查是否存在该位置是否存在任何文件,导致有时读取不完整的 xml 文件并在解析时引发错误。
我写了一个代码来只读那些可以在读写模式下访问的文件,这似乎在windows环境下工作,但在linux上失败。
在windows上运行的代码sn-p如下:
listOfFiles = folder.listFiles(new FileFilter()
public boolean accept(final File file)
try (RandomAccessFile stream = new RandomAccessFile(file, "rw"))
return true;
catch(final Exception e)
System.out.println("skipping file: file is not completely written");
return false;
);
有人可以帮我解决这个问题,为什么这段代码在 windows 上运行而不在 linux 上运行,或者有更好的解决方案吗?
【问题讨论】:
您遇到的异常是什么?请发帖 “消费者不断轮询以检查该位置是否存在任何文件” - 听起来像是WatcherService
的完美候选者
@Prashant 不幸的是,我在我的工作机器上遇到了这个异常,我不允许登录到 ***,因此我从我的个人机器上发布这个,我在个人机器上没有日志:但我得到异常说“文件过早结束”
如果您没有向我们提供可验证的最小问题,您希望我们如何提供帮助?
@Prashant 感谢关于使用观察者服务的建议。虽然我没有使用 watcherservice 方法,因为这意味着对这两个服务进行完全重新设计,然后再次测试已经投入生产的东西,但是如果我们计划将来迁移这两个服务,肯定会考虑使用它. +1 建议
【参考方案1】:
如果您依赖 R/W open 告诉您文件是否可用,则您使用了错误的技术。
鉴于可用的所有不同类型的文件系统,没有用于确保文件“完整”的内置 Java 机制。由于您控制流程的两端,因此解决方案非常简单。
将文件移动到要处理它们的位置的进程使用读取进程知道可以忽略的临时文件名格式写入文件。当写入过程完成文件的写入时,它会将文件重命名为读取过程知道已完成的名称格式。然后,根据定义,如果一个文件对读取过程是“可见的”,那么它就完成了。
步骤如下所示:
-
写入过程会在读取位置创建一个名为 TEMP_nnnn_ 的文件,其中选择 nnnn 以使文件名唯一。读取进程知道忽略名称以 TEMP 开头的文件。
写入过程将数据复制到文件中。
文件完成后,写入过程会关闭文件(将所有数据刷新到磁盘)并将其重命名为 FILE_nnnn_。
读取过程意识到 FILE_nnnn_ 并知道文件已准备好读取。
【讨论】:
感谢您的回答,我们终于采用了您建议的方法并且现在工作正常,我们不再收到错误。以上是关于具有读写模式的 RandomAccessFile 过滤器在 linux 环境下不起作用的主要内容,如果未能解决你的问题,请参考以下文章