获取文件描述后,就可以对文件进行读写操作。
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。