需要建议我的方法:读取正在连续写入的文件?

时间:2010-12-04 03:50:07

标签: java file io

我有一个csv文件,它是由脚本连续编写的。它每行写入时间戳和一些其他数据。我必须先阅读最新数据。 目前我在java中使用RandomAccessFile以反向方式读取文件。但随着它的不断写入,我必须优先阅读新数据。我正在维护已发送的时间戳并正在进行工作。这会导致不必要的扫描操作。

有没有更好的方法来处理这种情况?

提前致谢,

5 个答案:

答案 0 :(得分:1)

你可以考虑让一个线程在出现时读取新行并将它们推送到一堆未处理的行上,然后弹出堆栈的第二个线程以相反的顺序处理新行。

根据处理新行所需的时间与生成它们的速度相比,这可能就足够了。如果新行的生成速度比处理它们的速度快,那么这种方法可能无法正常工作 - 堆栈会变得太大而你的内存就会耗尽。在这种情况下,根据您的要求,您可能能够放弃一个丢弃旧条目的大小有限的堆栈。

答案 1 :(得分:1)

两个想法:

  1. 使用固定大小的记录格式而不是CSV。然后,您可以准确地确定记录的偏移量,而不必寻找新的线条。

  2. 如果无法做到这一点,请让一个线程从文件中读取项目并将其推送到堆栈中。另一个线程从堆栈中弹出项目并处理它们。因为它是一个堆栈,它将始终处理最新的可用项目。您需要弄清楚如何处理堆栈太大的情况。你只是想丢掉太旧的物品吗?

答案 2 :(得分:0)

如果您有权访问原始脚本,除CSV文件外,还要将记录写入数据库。然后你可以用数据库做任何你想做的事情;访问最后一条记录,运行报告等

答案 3 :(得分:0)

  

导致不必要的扫描操作。

我认为你指的是寻求某一点的开销,然后通过阅读找到下一个有效的CSV行开始位置,直到你点击下一个换行符。

我可以想到三种方法,这可能比你目前正在做的更有效:

  1. 读取整个文件并向前解析向前的行,将位置存储在内存中。然后以相反的顺序处理内存中的行。

  2. 从头开始查找行开始扫描文件,并将行开始位置存储在内存中。然后以相反的顺序迭代位置,寻求每一个读取相应的行。 (您可以通过在每次搜索中处理多行来更有效地完成输入。)

  3. 使用MappedByteBuffer将文件映射到内存中,然后您可以向前或向后单步执行字节缓冲区以查找行边界。

  4. 第一种方法要求您可以在内存中缓冲整个文件,但具有较低的I / O开销,因为您只需使用最少的系统调用读取文件一次。第三种方法具有相同的问题,但您可以将一个非常大的文件映射到(大)部分的内存中,以减少内存需求。

    但最终,没有简单有效的方法在Java中向后读取文件。

答案 4 :(得分:0)

如果您的应用程序在Unix环境中运行,则可以运行

tail -f /csv-file | custom-program

custom-program只接受标准输入并将其回显到与Java程序的套接字连接。

我假设您的Java程序是某种服务器应用程序,无法从命令行启动。如果这实际上没问题,那么你可以用Java程序替换自定义程序。