讀函數read
ssize_t read(int fd,void *buf,size_t nbyte)
作用:從文件描述符(fildes)相關聯的文件里讀入nbytes個字節的數據,並把它們放到數據區buf中。
read返回實際讀入的字節數,這可能會小於請求的字節數,如果read調用返回0,表示未讀入任
何數據,已到達了文件尾;如果返回-1,表示read調用出現了錯誤。
1 #include <stdio.h> 2 #include <unistd.h> 3 4 int main(void) 5 { 6 char buffer[128]; 7 int nread; 8 9 nread = read(0, buffer, 128); 10 if (-1 == nread) 11 write(2, "A read error has occurred\n", 26); 12 13 if ( (write(1, buffer, nread)) != nread ) 14 write(2, "A write error has occurred\n", 27); 15 16 return 0; 17 } 18
寫函數write
ssize_t write(int fd,const void *buf,size_t nbytes)
作用:把緩沖區(buf)的前nbytes個字節寫入與文件描述符(fildes)關聯的文件。
write返回實際寫入的字節數,如果文件描述符有錯誤或者底層設備的驅動程序對數據長度比
較敏感,表示在write調用中出現了錯誤,返回值可能會小於nbytes。如果函數返回0,表示
未寫入任何數據;返回-1表示write調用中出現了錯誤,錯誤代碼保存在全局變量errno中。
write可能會報告寫入的字節比要求的少,這不一定時錯誤,在程序中,需要檢查errno以發現
錯誤,然后再次調用write寫入剩余數據
1 #include <stdio.h> 2 #include <unistd.h> // write調用原型所在的頭文件 3 4 int main(void) 5 { 6 if ( (write(1, "Here is some data\n", 18)) != 18 ) 7 write(2, "A write error has occurred on file descriptor 1\n", 46); 8 9 return 0; 10}
read和write函數在字節流套接字上表現的行為和通常的文件I/O不同,字節流套接字上調用
read和write輸入或輸出的字節數可能比請求的數量少,然而這不是出錯狀態。這個現象的原
因在於內核用於套接字的緩沖區可能已達到了極限,此時需要多次調用read和write函數,以
輸入或輸出剩余字節。
《Unix 網絡編程》中用於在字節流套接字上的讀寫函數
1 ssize_t readn(int fd, void *vptr, size_t n) 2 { 3 size_t nleft; 4 ssize_t nread; 5 cahr *ptr; 6 ptr = vptr; 7 nleft = n; 8 9 while (nleft > 0) 10 { 11 if ( (nread = read(fd, ptr, nleft)) < 0 ) 12 { 13 if (errno == EINTR) 14 nread = 0; 15 else 16 return -1; 17 } 18 else if (nreda == 0) 19 { 20 break; 21 } 22 23 nleft -= nread; 24 ptr += nread; 25 } 26 27 return (n - nleft); 28 } 29 30 ssize_t writen(int fd, const void *vptr, size_t n) 31 { 32 size_t nleft; 33 ssize_t nwritten; 34 const char *ptr; 35 ptr = vptr; 36 nleft = n; 37 while (nleft > 0) 38 { 39 if ( (nwritten = write(fd, ptr, nleft)) <= 0 ) 40 { 41 if (nwritten < 0 && errno == EINTR) 42 nwritten = 0; 43 else 44 return -1; 45 } 46 47 nleft -= nwritten; 48 ptr += nwritten; 49 } 50 51 return n; 52 } 53 54 ssize_t readline(int fd, void *vptr, size_t maxlen) 55 { 56 ssize_t n, rc; 57 cahr c, *ptr; 58 ptr = vptr; 59 60 for (n = 1; n < maxlen; n++) 61 { 62 again: 63 if ( (rc = read(fd, &c, 1)) == 1 ) 64 { 65 *ptr++ = c; 66 67 if (c == '\n') 68 break; 69 } 70 else if (rc == 0) 71 { 72 *ptr = 0; 73 return (n -1); 74 } 75 else 76 { 77 if (errno == EINTR) 78 goto again; 79 return -1; 80 } 81 } 82 83 *ptr = 0; 84 85 return n; 86 }