具有读写模式的 RandomAccessFile 过滤器在 linux 环境中不起作用

RandomAccessFile filter with read write mode does not work on linux environment

我需要帮助来解决有关过滤尚未完全写入的文件的问题,因为在这种情况下我遇到了异常。

场景是:我有一个程序从队列中获取文件并将其放在服务器上的某个位置,另一个程序从该位置读取这些文件,这两个程序都在连续运行并且消费者不断轮询以检查如果该位置存在任何文件导致有时读取不完整 xml 文件并在 parisng 时抛出错误。

我写了一个代码来只读取那些可以在读写模式下访问的文件,它似乎在 windows 环境下工作但在 linux 上失败。

在windows上运行的代码片段如下:

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 上不是,或者有更好的解决方案吗?

如果您依赖于 R/Wopen 告诉您文件是否可用,那么您使用了错误的技术。

考虑到可用的所有不同类型的文件系统,没有内置 Java 机制来确保文件 "complete"。由于您控制流程的两端,因此解决方案非常简单。

将文件移动到要处理的位置的进程使用读取进程知道要忽略的临时文件名格式写入文件。当写入进程完成文件写入时,它会将文件重命名为读取进程知道已完成的名称格式。然后,根据定义,如果一个文件 "visible" 到读取过程它就完成了。

步骤看起来像这样:

  1. 写入过程在读取位置创建一个文件,命名为TEMP_nnnn_,其中选择nnnn以使文件名唯一。读取进程知道忽略名称以 TEMP.
  2. 开头的文件
  3. 写入进程将数据复制到文件。
  4. 文件完成后,写入过程将关闭文件(将所有数据刷新到磁盘)并将其重命名为 FILE_nnnn_。
  5. 读取进程意识到 FILE_nnnn_ 并且知道文件已准备好读取。