read()和write()
原创
©著作权归作者所有:来自51CTO博客作者荒唐了年少的原创作品,请联系作者获取转载授权,否则将追究法律责任
读函数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
转载请注明出处