#include <unistd.h>
ssize_t read(int fd, void *buf, size_t n);
// 返回:若成功则为读的字节数,若 EOF 则为0,若出错为 -1。
ssize_t write(int fd, const void *buf, size_t n);
// 返回:若成功则为写的字节数,若出错则为 -1。
read 函数从描述符为 fd 的当前文件位置复制最多 n 个字节到内存位置 buf。返回值 -1 表示一个错误,而返回值 0 表示 EOF。否则,返回值表示的是实际传送的字节数量。
write 函数从内存位置 buf 复制至多 n 个字节到描述符 fd 的当前文件位置。图 10-3 展示了一个程序使用 read 和 write 调用一次一个字节地从标准输入复制到标准输出。
图 10-3 一次一个字节地从标准输入复制到标准输出
旁注 - ssize_t 和 size_t 有些什么区别?
你可能已经注意到了,read 函数有一个 size_t 的输入参数和一个 ssize_t 的返回值。那么这两种类型之间有什么区别呢?在 x86-64 系统中,size_t 被定义为 unsigned long,而 ssize_t(有符号的大小)被定义为 long。read 函数返回一个有符号的大小,而不是一个无符号大小,这是因为出错时它必须返回 -1。有趣的是,返回一个 -1 的可能性使得 read 的最大值减小了一半。
实际上,除了 EOF,当你在读磁盘文件时,将不会遇到不足值,而且在写磁盘文件时,也不会遇到不足值。然而,如果你想创建健壮的(可靠的)诸如 Web 服务器这样的网络应用,就必须通过反复调用 read 和 write 处理不足值,直到所有需要的字节都传送完毕。