Linux下read和write的正确用法

我写这篇文章的目的是为了对read和write两个函数的用法做一个总结,同时提醒自己不要忘记:

一、原型介绍

#include <unistd.h>

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

参数:

fd: 将要读取数据的文件描述词。

buf:  所读取到的数据的内存缓冲。

count: 需要读取的数据量。

read()会把参数fd所指的文件传送nbyte个字节到buf指针所指的内存中。若参数nbyte为0,则read()不会有作用并返回0。返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或无可读取的数据。错误返回-1,并将根据不同的错误原因适当的设置错误码。

EAGAIN:打开文件时设定了O_NONBLOCK标志,并且当前没有数据可读取

EBADF:文件描述词无效,或者文件不可读

EFAULT:参数buf指向的空间不可访问

EINTR:数据读取前,操作被信号中断

EINVAL:一个或者多个参数无效

EIO:读写出错

EISDIR:参数fd索引的时目录

二、read和write的正确用法

①不完善的用法一:

int ret = read(fd, buf, len);

if(ret == -1){

exit(-1);

}else if(ret == 0){

close(fd);

}

忽略了 errno 的处理. 仔细看文档, 函数返回 -1 不能完全代表 fd 错误, 还需要结合 errno。

②不完善用法二:

int ret = read(fd, buf, len);

if(ret == -1){

if(errno == EINTR){

// 怎么办?

}else if(errno == EAGAIN){

// 怎么办

}

exit(-1);

}else if(ret == 0){

close(fd);

}

EINTR 表示 read() 函数调用被系统中断了, 调用者和 fd 都没有问题, 有问题的是操作系统。而
EAGAIN 是在非阻塞 IO 时会出现. 上面的代码判断了 errno, 但不知道下一步该怎么做, 还不行。

③正确用法

while(1){

int ret = read(fd, buf, len);

if(ret == -1){

if(errno == EINTR){

continue;

}else if(errno == EAGAIN){

// 根据你和调用者的约定, 返回一个数值告诉它再次重试

// 一般是结合 select/epoll 等 IO 多路复用函数

}

exit(-1);

}else if(ret == 0){

close(fd);

}

// proc

break;

}

write函数也有类似用法。

时间: 2024-10-24 20:54:52

Linux下read和write的正确用法的相关文章

linux下Bash编程循环语句特殊用法之编写脚本(十)

linux下Bash编程while语句特殊用法之编写脚本(十) 1.循环控制: break:中断整个循环语句,即退出循环后执行脚本后面的语句 continue:中断当前本次循环,提前进入下一轮循环 exit:结束脚本运行 2.while死循环,即当不知道循环多少次时 格式 : while :; do 循环语句 done 3.while从输入重定向文件中每行读取并赋值给read变量 格式:  while read LINE;do 循环语句 done < 路径文件 4.实例脚本 4.1.找出/etc

linux下定时任务的工具crontab的用法

Linux计划任务工具cron用法详解 linux下大名鼎鼎的计划任务工具crontab的使用介绍baidu.google上多得让人眼花缭乱,本着"天下文章一大抄"的觉悟,加上本人日常工作中总结的使用经验,索性推出这篇笔记式文章,以供遗忘时翻阅之用. cron是linux系统下一个自动执行指定任务的程序,即包含"时间"."路径"."自动执行脚本"等要素,例如我想通过自动执行脚本"newcopy.sh"在凌晨

linux下遍历文件夹---opendir等用法

首先要说肯定是头文件,#include <sys/types.h>   #include <dirent.h> linux下遍历文件夹需要用到以下几个函数,其中有三个是必须的,其它几个是可选的. DIR* opendir(const char * name);   失败返回NULL.成功返回DIR结构体.注意DIR前面没有struct,如果加上编译器会warning struct dirent *readdir(struct DIR* dir);   失败返回NULL. void

Linux 下 Shell 命令的分类及用法

导读 当你打算真正操纵好你的 Linux 系统,没有什么能比命令行界面更让你做到这一点.为了成为一个 Linux 高手,你必须能够理解 Shell命令的不同类型,并且会在终端下正确的使用它们. 在 Linux 下,命令有几种类型,对于一个 Linux 新手来说,知道不同命令的意思才能够高效和准确的使用它们.因此,在这篇文章里,我们将会遍及各种不同分类的 Linux Shell 命令.需要注意一件非常重要的事:命令行界面和 Shell 是不同的,命令行界面只是为你提供一个访问 Shell 的方式.

Linux下GoAccess的安装与全部用法

  GoAccess用户文档 一. GoAccess概述 1.1 GoAccess概述 goaccess是一个实时的web日志分析器,以及交互式查看器,在类Unix系统的终端(terminal)上运行,是一个基于GPL的自由软件.为需要可视化服务器报告的系统管理员提供快速而重要的HTTP统计信息.首先它会解析web日志文件,从被解析文件中收集数据,然后展示在控制台(console)或者X终端上.收集到的信息会在一个可视化/交互式的窗口中展示给用户,包括: 一般统计 该面板提供了几个指标的摘要,其

Linux下的PATH环境变量详细用法

linux PATH环境变量全解析 关于PATH的作用: PATH说简单点就是一个字符串变量,当输入命令的时候LINUX会去查找PATH里面记录的路径. 比如在根目录/下可以输入命令ls, 在/usr目录下也可以输入ls, 但其实ls这个命令根本不在这个两个目录下. 事实上当你输入命令的时候LINUX会去/bin,/usr/bin,/sbin等目录下面去找你此时输入的命令, 而PATH的值恰恰就是/bin:/sbin:/usr/bin:--. 其中的冒号使目录与目录之间隔开. 关于新增自定义路径

【转】基于linux下的变量声明declare的用法

转自:http://techcurtman.iteye.com/blog/1249512 declare 功能介绍:声明变量的属性,如果使用declare,后面没有任何参数,那么bash就会主动将所有变量名与内容都调出来,just as set. 语    法:declare [-aixr] variable 参数说明: -a  :将后面的variable定义为数组 -i  :将后面的variavle定义为整数数字 -x  :用法与export一样,就是将后面的variable变成环境变量 -r

Linux下串口通信工具minicom的用法

一.查看串口设备 例如,将USB转串口线插入交换机Console口后,执行命令:$ll /dev/ttyUSB* 二.连接串口设备 $sudo minicom -D /dev/ttyUSB0 三.设置串口参数 在minicom中按CTRL+A,O,配置串口速率9600,8位,无奇偶校验,保存 四.查看minicom配置文件 [email protected]:~$ cat .minirc# Machine-generated file - use setup menu in minicom to

linux下vi编辑器backspace不能正确删除文字

主要是由于安装的是vim.tiny版本,不是vim完整版.两种方法:1.直接在终端输入命令 sudo apt-get install vim ,按步操作安装好vim即可. 2. 修改/etc/vim/vimrc.tiny 文件,将set compatible 设置成set nocompatible ,添加 set backspace=2 这是因为有时候系统会默认vim兼容vi,所以使用vi的命令.