writen函数定义
#include <unistd>
ssize_t write(int filedes, void *buf, size_t nbytes);
// 返回:若成功则返回写入的字节数,若出错则返回-1
// filedes:文件描述符
// buf:待写入数据缓存区
// nbytes:要写入的字节数
在unp1中对writen进行了封装
ssize_t /* Write "n" bytes to a descriptor. */
writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (nwritten < 0 && errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
/* end writen */
void
Writen(int fd, void *ptr, size_t nbytes)
{
if (writen(fd, ptr, nbytes) != nbytes)
err_sys("writen error");
}
read函数定义
#include <unistd>
ssize_t read(int filedes, void *buf, size_t nbytes);
// 返回:若成功则返回读到的字节数,若已到文件末尾则返回0,若出错则返回-1
// filedes:文件描述符
// buf:读取数据缓存区
// nbytes:要读取的字节数
unp1中对read的封装
ssize_t /* Read "n" bytes from a descriptor. */
readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
/* end readn */
ssize_t
Readn(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
if ( (n = readn(fd, ptr, nbytes)) < 0)
err_sys("readn error");
return(n);
}
有几种情况可使实际读到的字节数少于要求读的字节数:
- 1 读普通文件时,在读到要求字节数之前就已经达到了文件末端。例如,若在到达文件末端之前还有30个字节,而要求读100个字节,则read返回30,下一次再调用read时,它将返回0(文件末端)。
- 2当从终端设备读时,通常一次最多读一行。
- 3当从网络读时,网络中的缓存机构可能造成返回值小于所要求读的字结束。
- 4当从管道或FIFO读时,如若管道包含的字节少于所需的数量,那么read将只返回实际可用的字节数。
- 5当从某些面向记录的设备(例如磁带)读时,一次最多返回一个记录。
- 6当某一个信号造成中断,而已经读取了部分数据。