You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中无法越过EOF读取文件问题(类似tail -f实现)

问题分析与解决方案

你的核心问题是stdio库在遇到EOF后会持续标记文件为EOF状态,后续读取操作会直接返回EOF,不会重新检查文件是否有新内容。旧系统可能因实现细节自动重置了EOF标记,但新系统严格遵循C标准行为。

关键修复:清除EOF标记

每次轮询等待后,必须用clearerr(FILE_HANDLE)清除文件的错误/EOF标记,这样下一次读取操作才会重新尝试从文件中读取新增内容。

修改后的主循环代码如下:

// Main loop
while (1) {

  // Read all remaining file contents til exhausted for now
  if (use_getline)
    while (getline(&line, &line_size, FILE_HANDLE) != -1)
      printf("\nLINE: %s\n", line);
  else
    while (fgets(line_fgets, line_size_fgets, FILE_HANDLE) != NULL)
      printf("\nLINE: %s\n", line_fgets);

  // Make sure there wasn't an error reading file
  if (ferror(FILE_HANDLE)) {
    printf("Failed to read from file [%s]: %s\n", file_path, strerror(errno));
    return 1;
  }

  // 清除EOF标记,否则下一次读取会直接返回EOF
  clearerr(FILE_HANDLE);

  // Pause for file to grow (inotify code goes here)
  sleep(loop_sleep_seconds);
  printf("Try reading again\n");

}

额外优化建议

  • 缓冲策略调整:_IONBF无缓冲模式虽能保证实时性,但_IOLBF行缓冲模式在日志类追加文件场景下更高效,且不影响实时读取效果。
  • 处理文件截断场景:如果目标文件发生截断(比如日志轮转),当前程序会从原偏移量继续读取,可能出现乱码。生产环境中需检查文件inode是否变化,或偏移量是否超过文件大小,必要时重新打开文件。
  • 替换轮询为inotify:用inotify监听文件IN_MODIFY事件,可消除轮询延迟,提升响应速度并减少资源消耗。

内容的提问来源于stack exchange,提问作者MeSteve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:32:12