我们有一个多线程程序,它执行以下操作:
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/