获取文件描述后,就可以对文件进行读写操作。

1、读文件

ssize_t read(int fd, void* buf, size_t len);

参数:

  fd:文件描述符

  buf:存储读取缓存

  len:预计读取的字节数

返回值:

  实际读取的字节数。

描述:

  调用read后,系统会从fd参数所引用文件的当前位置读取len个字节,到buf中去。返回值是写入到buf的字节数目。执行成功,返回读取的字节数;失败返回-1,并设置erron。


read读取的所有可能结果:

  ①return == len。 正常

  ②0< return < len。两种情况,

    第一:读取过程被信号中断,可供读取的字节数大于0小于len,读过程中被中断

    第二:读取到len个字节之前到达了EOF。

     重新进行read()调用可把剩余的字节读进剩余的缓冲区。

  ③return == 0。eof

  ④被阻塞

  ⑤ return == -1 && erron == EINTR。开始读之前就被中断了

  ⑥ return == -1 && erron == EAGAIN。被阻塞,应该稍后再进行调用。

  ⑦ return == -1 && erron == otherValue。严重错误

读取文件code demo:

//要读取len个字节
ssize_t ret;
while(len != 0 && (ret=read(fd, buf, len))!=0){
    if(ret == -1){
       if(erron == EINTR){
          continue;
      }else if(erron == EAGAIN){
          sleep(1);
      }else{
      perror("read error");
       break;
      }        
    }
    len -= ret;
    buf += ret;
}


2、写文件

ssize_t write(int fd,const void* buf, size_t count);

参数:

  fd:文件描述符

  buf:要写入的字节缓冲

  count:要写入的字节数

返回值:

  实际上写入的字节数

描述:

  从buf开始将count个字节写入fd所指向文件的位置。执行成功后,文件位置会随之更新。write不像read会到达文件的eof位置,除了socket外,也不会只写入部分字节。

当返回部分字节时读取方法:

ssize_t ret, nr;
while(len != 0 && (ret = write(fd, buf, len)) != 0){
    if(ret == -1){
        if(errno == EINTR){
            continue;
        }
        perror("write");
        break;
    }
    len -=ret;
    buf += ret;
}

为了提高效率,内核把数据写入磁盘时,会有缓冲。缓冲时间可以通过参数

/proc/sys/vm/dirty_expire_centiseconds来设定此值。

tips:

  size_t/ssize_t是posix所规定的数据类型。32位系统上,他们分别代表unsigned int / int。