fgetc和 fputc有什么作用,使得在处理大块数据时使用fread或 fwrite可以避免哪些问题?

编程语言 2026-07-08

我正在编写一个基于字典的玩具式压缩程序,它通过 fgetcfputc 一次读取一个字节并写入一个字节。现在perf并没有明确显示这些调用是瓶颈,但我怀疑perf指的是那些必须等待I/O的指令。我知道在Linux上 fgetcfputc 有内部缓冲区,但我仍然很难想象逐字节读写会很高效。那么它们需要处理哪些如果我只在自己的缓冲区上使用 freadfwrite 并在那里逐字节处理时我不会需要处理的事情?我正在修改我的代码以测试性能。

据我直觉,它们可能要处理每个字节:

  • 锁定(这点POSIX fgetc_unlockedfputc_unlocked 没有)
  • ungetc
  • FILE 相关的处理

  • 宽字符流?

  • 在流上设置错误和EOF状态
  • 二进制/文本模式
  • Locale?

解决方案

这是我在查阅C11标准时所能找到的内容:

关于 fgetc [7.21.7.1 fgetc函数] 的基本功能,我无论如何都要做的是:

  1. 返回字符或EOF,推进文件位置指示符
  2. 更新缓冲区位置,如果缓冲区为空就重新填充缓冲区 ["intended" 7.21.3 Files第 3段]

我不需要做的其他开销:

  1. 在遇到EOF时,在流上设置eof指示符(这也是 feof() 使用的)
  2. 在遇到其他错误时,在流上设置error指示符(这也是 ferror() 使用的)
  3. 如果尚未设置,将流的定向设置为字节流 [7.21.2.4流定向]
  4. 处理 ungetc 推回缓冲区,至少1 个字符 [7.21.7.10 ungetc函数]

关于 fputc [7.21.7.3 fputc函数] 的基本功能

  1. 将字符写入流,推进文件位置指示符
  2. 更新缓冲区位置,如果缓冲区已满则将其冲洗 ["intended" 7.21.3 Files第 3段]

我不需要做的其他开销:

  1. 返回写入的字符,若发生写错误,则在流上设置error指示符并返回EOF
  2. 如果尚未设置,将流的定向设置为字节流 [7.21.2.4流定向]
  3. 在追加模式("a" 及变体)下,强制写入当前的文件末尾,无论 fseek 如何 [7.21.5.3 fopen函数]

fread/fwrite 仍然有一些开销,但它们每次只在我的缓冲区上被调用一次。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章