1. Readn and Writen
1.1 Base Consolidation : Return values for read and write functions
1.1.1 Read function prototype is: ssize_t read (int fd, void* buf, size_t count); (void * In standard C means that a pointer of any type can assign a value to it, ssize_t is a signed integer) and its return value is as follows:
A) successfully returns the number of bytes read, which may be equal to count or less than count (when the count > file size returns the actual number of bytes read);
b) At the beginning of the reading, the EOF is returned 0;
c) Read failure return-1, and set the corresponding errno.
the prototype of the 1.1.2 write function is:ssize_t Write (int fd, const void *buf, size_t count); Its return value is as follows:
A) The number of bytes written successfully returned, as in this case;
b) write failure return-1, and set the corresponding errno;
c) When the return value is 0 o'clock, indicating that nothing is written in, this situation may occur in socket programming because the connection is closed and will not normally appear when writing disk files.
1.2 Why encapsulate a readn function and writen function , what are the flaws in the existing read function and write?
This is because when you call the read (or write) function, the return value of the read (write) One time may not be the number of bytes we want to read (that is, the count parameter in the Read function), which often occurs when the pipe is read or the number of networks goes away.
1.3 READN functions and Writen functions
The 1.3.1 Readn guarantees that n bytes must be read without encountering EOF . It has a return value of three kinds:
A) >0, indicating the number of bytes successfully read, if less than N, the middle of the description encountered EOF;
b) ==0 indicates that EOF is encountered at first reading;
c)-1 indicates an error (errno here is definitely not eintr).
The 1.3.2 writen function guarantees that it must be full of n bytes and return a value:
a) N indicates a successful write N of bytes
b)- 1 Write failed (there is no eintr error here)
1.3.3 source code is as follows, for example , when calling Readn (FD, BUF, 20) in a while loop to read a file with a size of 55 bytes, the READN function is called 4 times
A) returns 20 for the first time;
b) return 20 for the second time;
c) The third return 15 (here in the READN function will be called 2 times the Read function, the first time can only read 15 bytes, because to EOF, at this time the difference of 5 bytes, reread when read directly return 0);
D) return 0 for the fourth time, indicating that the file reads, jumps out while, and does not enter the while interior.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #define ERR_EXIT (m) do { Perror (m); Exit (Exit_failure); }while (0)/* * READN and Wirten functions */ssize_t readn (int fd, void *buf, int n); ssize_t writen (int fd, void *buf, int n);/* * HERE The READN function successfully returns the number of bytes read * If the number of bytes is less than n must have encountered EOF * ERROR returned-1 Here the error must not contain EINTR * First encountered EOF return 0 */ssize_t readn (int fd, void *buf, in T n) {size_t nleft = n;//number of bytes to be read char *bufptr = BUF;//point to the Read function where the data is currently stored ssize_t nread; while (Nleft > 0) {if (nread = Read (FD, BUFPTR, N)) < 0) {if (errno = = eintr) {//Interrupt encountered Continue } else//other error return-1; } else if (nread = = 0) {//encountering EOF break; } nleft-= Nread; BufPtr + = Nread; } return (N-nleft);} /* * writen must be here.Must write n bytes * Less than n is an error * return N or-1 */ssize_t writen (int fd, void *buf, int n) {size_t nleft = n; char *bufptr = BUF; ssize_t Nwrite; while (Nleft > 0) {if (Nwrite = Write (fd, BUFPTR, N)) <= 0) {if (errno = = eintr) nwri Te = 0; else return-1; } nleft-= Nwrite; BufPtr + = Nwrite; } return N; Note that this must be n because here the guaranteed N bytes are written}int main (int argc, const char *argv[]) {char buf[20] = {0}; int fd = open ("Test.txt", o_rdonly); if (fd = =-1) {Err_exit ("open"); } int ret; while (printf ("-----call READN----\ n"), (ret = READN (FD, buf)) > 0) {writen (Stdout_fileno, buf, ret); } close (FD); return 0;}
2. ReadLine function
2.1 readline function: ssize_t readline (int fd, void *usrbuf, size_t maxlen), its return value:
A) Error return-1, excluding eintr;
b) meet \ n during the fetch process;
c) did not touch \ n, but read a full maxlen-1 byte.
2.2 Source code.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #define ERR_EXIT (m) do { Perror (m); Exit (Exit_failure); }while (0)/* * Use read to implement ReadLine function read one byte at a time to determine if \ n * */ssize_t readline (int fd, void *usrbuf, size_t maxlen) {char * BufPtr = Usrbuf; char c; size_t nleft = maxlen-1; Reserve a position int nread for the. while (Nleft > 0) {if (nread = Read (FD, &c, 1)) < 0) {if (errno = = eintr) {Conti Nue } else return-1; } else if (nread = = 0) {//eof break; } *bufptr++ = C; Nleft--; if (c = = ' \ n ') {//meet \ n to end break; }} *bufptr = ' + '; Return (Maxlen-1-nleft);} int main (int argc, const char *argv[]) {int FD = open ("Test.txt", o_rdonly); if (fd = =-1) { Err_exit ("open"); } char buf[1024] = {0}; int ret; while (ret = ReadLine (FD, buf, +)) > 0) {printf ("ret =%d\nbuf =%s", ret, buf); } return 0;}
2.3 Readn, writen, readline belong to the same series, called the three functions of network programming.
3. RIO a buffer-implemented IO system
3.1 The writing idea of Rio_read function in Rio:
A) adopt Pre-reading scheme to read the data into buffer in advance;
b) every time the user fetches the data, it reads from buffer , rather than using the system to call the Read function, which reduces the overhead of using the system call more than once.
3.2 The writing principle of the Rio_read function : it must be semantically consistent with the read function of the system, which means that the return value of Rio_read has three cases:
A)-1 represents an error, this does not contain eintr;
b) 0 for EOF, read end;
c) >0 indicates the number of bytes read.
3.3 Source code implementation see.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #define ERR_EXIT (m) do { Perror (m); Exit (Exit_failure); }while (0) #define Buf_len 8192/* * RIO a IO system with buffers * each read is read from the buffer instead of the system call * */typedef struct{int fd_; To read the FD size_t Nleft_; Buffer remaining Available bytes of data char *bufptr_; Points to the ending address of the remaining available data char Buffer_[buf_len];} Rio_t;void Rio_init (rio_t *rp, int fd); ssize_t rio_read (rio_t *rp, void *usrbuf, size_t n); ssize_t Rio_readn (Rio_t *rp, VO ID *usrbuf, size_t n); ssize_t rio_readline (rio_t *rp, void *usrbuf, size_t maxline); ssize_t rio_writen (int fd, void *usrbu F, size_t N); void Rio_init (rio_t *rp, int fd) {//Initialize a Rio rp->fd_ = FD; Rp->nleft_ = 0; Rp->bufptr_ = Rp->buffer_;} ssize_t Rio_read (rio_t *rp, void *usrbuf, size_t n) {//pre-read data into buffer int nread; while (Rp->nleft_ = = 0) {//Current bufferNo data is available if ((Nread = Read (Rp->fd_, rp->buffer_, sizeof (RP->BUFFER_))) < 0) {if (errno = = Eint R) {continue; } else return-1; } else if (nread = = 0) {//EOF return 0; } Rp->nleft_ = Nread; RP->BUFPTR_ = rp->buffer_;//Reset buffer pointer}//This time the buffer already has data int cnt = n; if (Rp->nleft_ < n)//buffer can provide less than the number of bytes required by the user CNT = rp->nleft_; memcpy (Usrbuf, RP->BUFPTR_, CNT); Rp->nleft_-= CNT; Reduced number of bytes available after reading rp->bufptr_ + = CNT; return CNT;} ssize_t Rio_readn (rio_t *rp, void *usrbuf, size_t N) {char *bufptr = usrbuf; size_t nleft = n; size_t Nread; while (Nleft > 0) {if (Nread = Rio_read (RP, BufPtr, nleft)) = =-1) {//neft return-1; } else if (nread = = 0) {break; } nleft-= Nread; BufPtr + = Nread; } return (N-nleft);} ssize_t Rio_readline (rio_t *rp, VOID *usrbuf, size_t maxline) {size_t nleft = maxline-1; char *bufptr = usrbuf; char c; int nread; while (Nleft > 0) {if (Nread = Rio_read (RP, &c, 1)) = =-1) return-1; else if (nread = = 0) {break; } *bufptr++ = C; Nleft--; if (c = = ' \ n ') break; } *bufptr = ' + '; Return (Maxline-1-nleft);} ssize_t rio_writen (int fd, void *usrbuf, size_t N) {char *bufptr = usrbuf; size_t nleft = n; size_t Nwrite; while (Nleft > 0) {if (Nwrite = Write (fd, BUFPTR, N)) < 0) {if (errno = = eintr) Conti Nue else return-1; } nleft-= Nwrite; BufPtr + = Nwrite; } return n;} int main (int argc, const char *argv[]) {rio_t R; int fd = open ("Test.txt", o_rdonly); if (fd = =-1) {Err_exit ("open"); } rio_init (&r, FD); int ret; Char buf[50] = {0}; while (ret = Rio_readline (&r, BUF, >0) {Rio_writen (Stdout_fileno, buf, ret); } return 0;}