apue标准IO库那些事儿,都有哪些细节和用法?

摘要:提起标准 IO 库,第一印象就是 printfscanf,这有什么可说的?但是一个流是如何处理宽窄字符集、缓存方式的?如何在程序内部将标准输出重定向到文件?FILE* 与 fd 是如何相互转换的?在处理大文件时 fseekfseeko
前言 标准 IO 库自 1975 年诞生以来,至今接近 50 年了,令人惊讶的是,这期间只对它做了非常小的修改。除了耳熟能详的 printf/scanf,回过头来对它做个全方位的审视,看看到底优秀在哪里。 打开关闭 要想使用 IO 流就必需打开它们。三个例外是标准输入 stdin、标准输出 stdout、标准错误 stderr,它们在进入 main 时就准备好了,可以直接使用,与之对应的文件描述符分别是 STDIN_FILENO / STDOUT_FILENO / STDERR_FILENO。除此之外的流需要打开才能使用: FILE* fopen(const char * restrict path, const char * restrict mode); FILE* fdopen(int fildes, const char *mode); FILE* freopen(const char *path, const char *mode, FILE *stream); FILE* fmemopen(void *restrict *buf, size_t size, const char * restrict mode); fopen 用于打开指定的文件作为流 fdopen 用于打开已有的文件描述符作为流 freopen 用于在指定的流上打开指定的文件 fmemopen 用于打开已有的内存作为流 大部分打开操作都需要提供 mode 参数,它主要由 r/w/a/b/+ 字符组成,相关的组合与 open 的 oflag 参数对应关系如下: mode oflag r O_RDONLY r+ O_RDWR w O_WRONLY | O_CREAT | O_TRUNC w+ O_RDWR | O_CREAT | O_TRUNC a O_WRONLY | O_CREAT | O_APPEND a+ O_RDWR | O_CREAT | O_APPEND 其中 b 表示按二进制数据处理,不提供时按文本数据处理,不过 unix like 的文件不区分二进制数据与文本数据,加不加没什么区别,所以上面没有列出。 fdopen 提供了一种便利,将已有的 fd 封装在 FILE* 中,特别当描述符是通过接口传递进来时就尤为有用了。
阅读全文