【问题标题】:Reading from file which is being modified with C从正在用 C 修改的文件中读取
【发布时间】:2012-08-30 23:01:10
【问题描述】:

我有一个程序正在将结果写入文件,我想从该文件中实时读取。这是一个普通的文本文件,外部程序总是写一整行。我只需要在 Linux 系统上运行它。

int last_read = 0;
int res;
FILE *file;
char *buf;
char *end = buf + MAXLINE - 1;
int c;
int fileSize;
char *dst;
while (external_programme_is_running()) {
   file = fopen(logfile, "r"); //without opening and closing it's not working
   fseek(file, 0, SEEK_END);
   fileSize = ftell(file);
   if (fileSize > last_read) {
      fseek(file, last_read, SEEK_SET);
      while (!feof(file)) {
        dst = buf;
        while ((c = fgetc(file)) != EOF && c != '\n' && dst < end)
            *dst++ = c;
        *dst = '\0';
        res = ((c == EOF && dst == buf) ? EOF : dst - buf);

         if (res != -1) {
            last_read = ftell(file);
            parse_result(buf)
         }
      }
  }
  fclose(file);
}

这是正确的方法吗?或者检查修改时间然后打开文件会更好吗?如果同时修改文件,是否可能导致读取崩溃?

【问题讨论】:

  • 漂亮的比赛条件蛋糕...
  • 为什么不使用管道?那么您不必经历文件共享、打开和查找的麻烦。看到这个:stackoverflow.com/questions/1072125/…
  • 外部程序由便携式批处理系统(PBS 队列)调度。当达到壁时间(超时)时,PBS 是否也会杀死管道进程?

标签: c unix


【解决方案1】:

为避免每次循环迭代都需要关闭、重新打开和重新搜索,请在读取 EOF 后在流上调用 clearerr

【讨论】:

    【解决方案2】:

    如果您在其他程序写入的同时阅读,您应该不会有任何问题。最糟糕的情况是直到下次打开文件时才能看到写入的内容。

    此外,您将最后一次查找位置与文件末尾进行比较的方法是查找文件添加内容的好方法,因为外部程序只是编写额外的行。不过,我建议您在循环结束时添加 sleep(1),这样您就不会使用大量 CPU。

    【讨论】:

    • 谢谢。是的,我在函数 external_programme_is_running() 中有一个 sleep(1),这也需要一些时间
    【解决方案3】:

    在另一个进程正在写入文件时读取文件没有问题。标准的tail -f 实用程序经常用于此目的。

    唯一需要注意的是,写入过程不能以独占方式锁定文件。

    关于您的读取代码(即使用fgetc()),由于您说写入过程将一次写入一行,您可能需要查看fgets()

    【讨论】:

    • 我猜tail -f 不会改变任何东西,文件只会被其他进程修改。是的,fgets() 会使代码更具可读性,但无论如何我都必须检查行尾
    猜你喜欢
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 2014-11-25
    • 2019-12-22
    • 1970-01-01
    相关资源
    最近更新 更多