- 這兩個函數是自己實作的,不是系統自帶的
一、引入
管道,FIFO以及某些裝置(特别是終端和網絡)具有以下兩種性質:
- 一次read操作所傳回的資料可能少于所要求的資料,即使還沒達到檔案尾端。這不是 一個錯誤,應當繼續讀該裝置
- 一次write操作的傳回值也可能少于指定輸出的位元組數。這可能是由若幹因素造成的, 例如,核心輸出緩沖區變滿。這也不是錯誤,應當繼續寫餘下的資料至該裝置。(通常, 隻有對非阻塞描述符,或捕捉到一個信号時,才發生這種write傳回)
在讀、寫磁盤檔案時沒有這兩種性質,除非檔案系統用完了空間,或者接近了配額限制,不能将要求寫的資料全部寫出
二、函數引入
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CNwEDMxYTM0QTO0AjNllDN5MWOhFGMzImNjljYhFDMm9CX3IzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL2M3Lc9CX6MHc0RHaiojIsJye.png)
#include "apue.h"
ssize_t readn(int fd, void *buf, size_t nbytes);
ssize_t writen(int fd, void *buf, size_t nbytes);
傳回值
- 兩個函數傳回:已讀、寫位元組數,若出錯則為-1
三、函數的實作
#include<unistd.h>
ssize_t readn(int fd, void *ptr, size_t n)
{
size_t nleft;
ssize_t nread;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount read so far */
} else if (nread == 0) {
break; /* EOF */
}
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
#include<unistd.h>
ssize_t writen(int fd, const void *ptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) < 0) {
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount written so far */
} else if (nwritten == 0) {
break;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n - nleft); /* return >= 0 */
}