【问题标题】:Read a file while it's being written在写入文件时读取文件
【发布时间】:2010-12-16 11:21:58
【问题描述】:

我必须读取tomcat日志文件,一段时间后(例如:一个小时)我会再次读取文件(只是为了新添加的内容),所以我创建了RandomAccessFile来记录我完成的最后一个位置,并使用 BufferedReader.readLine() 方法。

但是,我发现有时我无法读取文件的整行。

例如,tomcat正在写如下内容(只是示例):

192.168.0.0 本地主机 /index.html .....

此时,当我阅读时,我可能会得到结果:

192.168.0 0 本地主机 /index.html .....

192.168.0.0 本地主机 /index.html .....

也就是说,如果正在写这行,我的读者读到了一个不完整的行。

所以我想知道确定正在阅读的行是否已经完成?

这是核心代码:

raf = new RandomAccessFile(file, "r");
raf.seek(pos);
while ((line = raf.readLine()) != null) {
    System.out.println(line);
}
pos = raf.getFilePointer();
raf.close();

我已经试过了(添加条件):

raf = new RandomAccessFile(file, "r");
raf.seek(pos);
while ((line = raf.readLine()) != null) {
    if(line.chartAt(line.length()-1)=='\n'){
        System.out.println(line);
    } else
        raf.seek(pos); //roll back to the last position

}
pos = raf.getFilePointer();
raf.close();

但它不起作用..

有什么想法吗?

【问题讨论】:

  • 也许总是跳过最后一行?

标签: java concurrency io random-access


【解决方案1】:

readLine 使用换行符。您不能使用它来确定您是否有完整的线路。您需要一次读取一个字节并自己解析该行。

当你得到一条有效线时,你并没有在这个位置上移动..

【讨论】:

  • 字节 b; while ((b= raf.readByte()) != -1) { //如何检查此字节是否为 EOL? }
  • 另外,我从 readByte() 中得到了一个字节,但行分隔符是一个字符串:system.getProperty("line.separator");如何比较它们?
  • @hguser,您不应该假设您输入的新行与系统默认值匹配。相反,您应该允许 \r、\n 或 \r\n
【解决方案2】:

readLine() 去除 EOL 字符,因此您看不到它。从它的角度来看,EOF 和 EOL 之间没有区别,这在您的情况下很麻烦。除了 Peter 的解决方案之外,您还可以尝试在阅读该行并检查它是否为 EOL 后返回一个字节。不过要小心使用的行尾样式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 2020-06-24
    • 2011-12-16
    • 1970-01-01
    相关资源
    最近更新 更多