java - 当写入未完成时如何检测我正在读取文件?

标签 java multithreading file-io concurrency java-io

我们有一个多线程程序,它执行以下操作:

thread_1 是硬盘的监听器,用于检测创建的​​新文件。我们在 Java 7 中使用 WatchService api。当另一个程序创建新文件时,thread_1 会检测并获取它并将其放入 PriorityBlockingQueue例如:

priorityBlockingQueue.add(FileObject)

FileObjComparator 是一个自定义对象实现比较器。它按创建时间和 FileObject 中的 fileCreatedTime 字段排序,当检测到此文件时,我从系统时间获取:

 public int compare(FileObject o1, FileObject o2) {
        return o1.getFileCreatedTime().compareTo(o2.getFileCreatedTime());
    }

priorityBlockingQueue 初始化为:

DataFileQueue.priorityBlockingQueue = new PriorityBlockingQueue<FileObject>(100000, new FileObjComparator());

Thread_2 将处理此 priorityBlockingQueue 中最后一个文件旁边的文件

if(priorityBlockingQueue.size) > 1)
   process(priorityBlockingQueue.poll());

2 个线程并行运行,但当我处理多个大文件时,有时 Thread_2 会在文件写入时处理该文件。我检测到这一点是因为重新检查内容文件和处理结果。

该程序运行在Centos 6.2上,该硬盘分区以异步模式挂载。感谢您的帮助。

最佳答案

如果您确实正在处理倒数第二个文件,那么我很惊讶它的大小正在增长,除非多个进程或线程正在生成输入文件。确保创建文件的其他进程在写入下一个文件之前刷新并关闭每个文件。

  • 您可以分块读取文件,然后返回一段时间以查看是否有任何其他数据添加到文件中,并在当时使用 RandomAccessFile 对其进行处理。如果您正在逐行读取文件,则不幸的是您需要自己进行分页。如果文件是基于行的,那么您应该确保行终止符关闭文件。

  • 您可以尝试的另一件事是稍微延迟文件的处理,以便让文件系统刷新其缓冲区。丑陋且不可靠,但也许是必要的。

  • 如果您可以调整输出过程,那么您可以使用魔术字符串结束文件,然后在看到魔术字符串之前不处理文件。

  • 您可以让进程写入文件,将文件的大小写入带有“.size”扩展名(或其他名称)的单独文件中。大小文件将帮助您验证您正在阅读的字符数是否正确。

  • 如果您在 ~unix 上运行,另一件事是在开始读取文件以同步文件系统之前执行 Runtime.exec("/bin/sync");系统。问题是对此的支持高度依赖于操作系统。它也可能成为真正的性能 killer 。他是我 Mac 上的手册页:

    The sync utility can be called to ensure that all disk writes have been completed

关于java - 当写入未完成时如何检测我正在读取文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11332827/

相关文章:

c - 使用 "fread"获得意外输出

c - fwrite() 性能远低于磁盘容量

java嵌套Map数据结构读写操作

c - 从文本文件中读取单个单词并翻译 - C

java - 根据表元数据生成代码

java - TableViewer jface如何进行分页?

c++ - 尝试使用函数填充线程 vector - 错误

c# - 使用线程对 C# 事件中的循环进行计数

java - 使用 jackson 转换时 POJO 具有空值

Java 扩展泛型