linux 系统I/O 1

I/O 是主存和外部设备之间(终端,磁盘驱动器,网络)复制数据的过程,输入是从 从I/O设备复制数据到主存,输出是主存复制数据到I/O设备。

1.读写文件

ssize_t Read(int fd, void *buf, size_t count);
//返回: 若成功则返回读的字节数,若失败 则为-1,EOF则为0
//read函数从描述符为fd的当前文件为准复制最多n个字节到内存位置buf,一般返回值是实际传送的字节数量
ssize_t Write(int fd, const void *buf, size_t count);
//返回: 若成功则返回写的字节数,若失败 则为-1
//write函数从内存位置buf为准复制最多n个字节到描述符为fd的当前文件位置。 

ssize_t Read(int fd, void *buf, size_t count) //size_t 是unsigned_long型。
{
    ssize_t rc;//有符号大小的long型,因为有可能返回负值,所以类型是ssize_t.

    if ((rc = read(fd, buf, count)) < 0) 
    unix_error("Read error");
    return rc;
}

ssize_t Write(int fd, const void *buf, size_t count) 
{
    ssize_t rc;

    if ((rc = write(fd, buf, count)) < 0)
    unix_error("Write error");
    return rc;
}

下面是示例程序:

#include"csapp.h"

int main(void)
{
  char c;

  while(Read(STDIN_FILENO,&c,1)!=0) //把标准输入复制到标准输出。

    Write(STDOUT_FILENO,&c,1);
      exit(0);

}

zsj@zsj-virtual-machine:~/ccode$ gcc -o iotest2 iotest2.c -lpthread
zsj@zsj-virtual-machine:~/ccode$ ./iotest2
w  
w
wert
wert
dgfdhfhfgh
dgfdhfhfgh


用RIO健壮的读写

RIO会自动的为您处理不足值,在像网络程序这种容易出现不足值的应用中,RIO提供了方便、健壮、高效的I/O.

RIO函数分类:

(1)RIO无缓冲的输入输出函数

rio_readn  //函数从描述符为fd的当前文件为准复制最多n个字节到内存位置buf,遇到EOF时返回一个不足的值 
rio_writen //函数从内存位置buf为准复制最多n个字节到描述符为fd的当前文件位置
/* $begin rio_readn */  
ssize_t rio_readn(int fd, void *usrbuf, size_t n) //rio_readn源码
{
    size_t nleft = n;
    ssize_t nread;
    char *bufp = (char *)usrbuf;

    while (nleft > 0) {
    if ((nread = read(fd, bufp, nleft)) < 0) {
        if (errno == EINTR) /* interrupted by sig handler return */
        nread = 0;      /* and call read() again */
        else
        return -1;      /* errno set by read() */ 
    } 
    else if (nread == 0)
        break;              /* EOF */
    nleft -= nread;
    bufp += nread;
    }
    return (n - nleft);         /* return >= 0 */
}
/* $end rio_readn *


/*
 * rio_writen - robustly write n bytes (unbuffered)
 */
/* $begin rio_writen */
ssize_t rio_writen(int fd, void *usrbuf, size_t n)// rio_writen 源码
{
    size_t nleft = n;
    ssize_t nwritten;
    char *bufp = (char *)usrbuf;

    while (nleft > 0) {
    if ((nwritten = write(fd, bufp, nleft)) <= 0) {
        if (errno == EINTR)  /* interrupted by sig handler return */
        nwritten = 0;    /* and call write() again */
        else
        return -1;       /* errno set by write() */
    }
    nleft -= nwritten;
    bufp += nwritten;
    }
    return n;
}
/* $end rio_writen */

(2)RIO带缓冲的输入输出函数

/* $begin rio_read */
static ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n)
{
    int cnt;

    while (rp->rio_cnt <= 0) {  /* refill if buf is empty */
    rp->rio_cnt = read(rp->rio_fd, rp->rio_buf, 
               sizeof(rp->rio_buf));
    if (rp->rio_cnt < 0) {
        if (errno != EINTR) /* interrupted by sig handler return */
        return -1;
    }
    else if (rp->rio_cnt == 0)  /* EOF */
        return 0;
    else 
        rp->rio_bufptr = rp->rio_buf; /* reset buffer ptr */
    }

    /* Copy min(n, rp->rio_cnt) bytes from internal buf to user buf */
    cnt = n;          
    if (rp->rio_cnt < n)   
    cnt = rp->rio_cnt;
    memcpy(usrbuf, rp->rio_bufptr, cnt);
    rp->rio_bufptr += cnt;
    rp->rio_cnt -= cnt;
    return cnt;
} 
/* $end rio_read */

/*

/* 
 * rio_readlineb - robustly read a text line (buffered)
 */
/* $begin rio_readlineb */
ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen) 
{
    int n, rc;
    char c, *bufp = (char *)usrbuf;

    for (n = 1; n < maxlen; n++) { 
    if ((rc = rio_read(rp, &c, 1)) == 1) {
        *bufp++ = c;
        if (c == '\n')
        break;
    } else if (rc == 0) {
        if (n == 1)
        return 0; /* EOF, no data read */
        else
        break;    /* EOF, some data was read */
    } else
        return -1;    /* error */
    }
    *bufp = 0;
    return n;
}
/*
 * rio_readinitb - Associate a descriptor with a read buffer and reset buffer
 */
/* $begin rio_readinitb */
void rio_readinitb(rio_t *rp, int fd) 
{
    rp->rio_fd = fd;  
    rp->rio_cnt = 0;  
    rp->rio_bufptr = rp->rio_buf;
}
/* $end rio_readinitb */

/*
 * rio_readnb - Robustly read n bytes (buffered)
 */
/* $begin rio_readnb */
ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n) 
{
    size_t nleft = n;
    ssize_t nread;
    char *bufp = (char *)usrbuf;

    while (nleft > 0) {
    if ((nread = rio_read(rp, bufp, nleft)) < 0) {
        if (errno == EINTR) /* interrupted by sig handler return */
        nread = 0;      /* call read() again */
        else
        return -1;      /* errno set by read() */ 
    } 
    else if (nread == 0)
        break;              /* EOF */
    nleft -= nread;
    bufp += nread;
    }
    return (n - nleft);         /* return >= 0 */
}
/* $end rio_readnb */

/* 

(3)读取元数据

应用程序能够通过调用 stat 和fastat 函数,检索关于文件的信息。

void Stat(const char *filename, struct stat *buf) 
{
    if (stat(filename, buf) < 0)
    unix_error("Stat error");
}

void Fstat(int fd, struct stat *buf) 
{
    if (fstat(fd, buf) < 0)
    unix_error("Fstat error");
}

应用程序可以用readdir系列函数来读取目录的内容
函数 closedir关闭流释放其所有资源。

(4)共享文件

(5)I/O重定向

(6)标准I/O

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值