read()和write()


讀函數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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM