一、在POSIX中的定義
#include <unistd.h> ssize_t read(int fd, void *buf, size_t len);
二、調用read()的可能結果
2.1 返回值為len;讀取到的所有len個字節都被存儲在buf中,結果和預期的一致;
2.2 返回值小於len大於0;讀取到的字節被存儲到buf中,原因:
(1)在讀取過程中信號中斷或在讀取中出錯;
(2)可讀的數據大於0字節小於len字節在讀取len字節之前到達EOF
2.3 返回0,表示EOF,沒有更多的數據可讀;
2.4 由於當前沒有數據可用,調用阻塞;在非阻塞模式下,不會發生這種情況;
2.5 返回-1,並把errno置為EINTR,這表示在讀取任何字節之前收到信號;調用可以重新執行;
2.6 返回-1,並把errno置為非EINTR或EAGAIN的一個值,這表示更嚴重的錯誤,重新執行讀操作不會成功
三、讀入所有字節
ssize_t ret;
while (len != 0 && (ret = read(fd, buf, len)) != 0) { if (ret == -1) { if (errno == EINTR) { continue; } perror("read"); break; } len -= ret; buf += ret; }
四、非阻塞讀
文件描述符以非阻塞模式打開(即open調用中指定參數O_NONBLOCK),並且沒有數據可讀,read調用會返回-1,並設置
errno值為EAGAIN,而不是阻塞;當以非阻塞模式讀文件時,必須檢查EAGAIN,否則可能因為丟失數據導致嚴重錯誤
char buf[BUFSIZ]; ssize_t nr; start: nr = read(fd, buf, BUFSIZ); if (nr == -1) { if (errno == EINTR) { goto start; } if (errno == EAGIN) { // 稍后重新讀取 } else { // 發生錯誤 } }