fgetc和 fputc有什么作用,使得在处理大块数据时使用fread或 fwrite可以避免哪些问题?
我正在编写一个基于字典的玩具式压缩程序,它通过 fgetc 和 fputc 一次读取一个字节并写入一个字节。现在perf并没有明确显示这些调用是瓶颈,但我怀疑perf指的是那些必须等待I/O的指令。我知道在Linux上 fgetc 和 fputc 有内部缓冲区,但我仍然很难想象逐字节读写会很高效。那么它们需要处理哪些如果我只在自己的缓冲区上使用 fread 或 fwrite 并在那里逐字节处理时我不会需要处理的事情?我正在修改我的代码以测试性能。
据我直觉,它们可能要处理每个字节:
- 锁定(这点POSIX
fgetc_unlocked和fputc_unlocked没有) ungetc?-
与
FILE相关的处理 -
宽字符流?
- 在流上设置错误和EOF状态
- 二进制/文本模式
- Locale?
解决方案
这是我在查阅C11标准时所能找到的内容:
关于 fgetc [7.21.7.1 fgetc函数] 的基本功能,我无论如何都要做的是:
- 返回字符或EOF,推进文件位置指示符
- 更新缓冲区位置,如果缓冲区为空就重新填充缓冲区 ["intended" 7.21.3 Files第 3段]
我不需要做的其他开销:
- 在遇到EOF时,在流上设置eof指示符(这也是
feof()使用的) - 在遇到其他错误时,在流上设置error指示符(这也是
ferror()使用的) - 如果尚未设置,将流的定向设置为字节流 [7.21.2.4流定向]
- 处理
ungetc推回缓冲区,至少1 个字符 [7.21.7.10 ungetc函数]
关于 fputc [7.21.7.3 fputc函数] 的基本功能
- 将字符写入流,推进文件位置指示符
- 更新缓冲区位置,如果缓冲区已满则将其冲洗 ["intended" 7.21.3 Files第 3段]
我不需要做的其他开销:
- 返回写入的字符,若发生写错误,则在流上设置error指示符并返回EOF
- 如果尚未设置,将流的定向设置为字节流 [7.21.2.4流定向]
- 在追加模式("a" 及变体)下,强制写入当前的文件末尾,无论
fseek如何 [7.21.5.3 fopen函数]
fread/fwrite 仍然有一些开销,但它们每次只在我的缓冲区上被调用一次。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。