linux常用文件操作IO(open-write-read)

linux常用文件操作IO

  • open()
  • write()
  • read()

1. open()系统调用

open()调用了sys_open()

/**
 * @brief open()函数原型之一
 * @param[*pathname] 指向文件名字符串
 * @param[flags] 系统调用的标志 
 * @param[mode] 请求传输的数据长度
 * @retval 打开成功返回文件描述符,失败返回-1;
 */
int fd = open(const char *pathname,int flags,mode_t mode)

1.1 flags参数定义如下:

  • O_RDONLY 只读
  • O_WRONLY 只写
  • O_RDWR 可读写
  • O_CREAT 如果文件不存在,就创建它
  • O_EXCL 对于O_CREAT标志,如果文件已经存在,则失败
  • O_NOCTTY 从不把文件看作控制终端
  • O_TRUNC 截断文件(删除所有现有内容)
  • O_APPEND 总是在文件末尾写
  • O_NONBLOCK 没有系统调用在文件上阻塞
  • O_NDELAY 与O_NONBLOCK功能相同(但会导致read的返回值不同)
  • O_SYNC 同步写(阻塞,直到物理写终止)
  • FASYNC 通过信号发出I/O事件通告
  • O_DIRECT 直接I/O传输(无内核缓冲)
  • O_LARGEFILE 大型文件(长度大于2GB)
  • O_DIRECTORY 如果文件不是一个目录,则失败
  • O_NOFOLOW 不解释路径名中尾部的符号链接
  • O_NOATIME 不更新索引节点的上次访问时间

1.2 open()完成如下工作:

  • 检查设备特定的错误(诸如设备未就绪或类似的硬件问题);
  • 如果设备是首次打开,则对其进行初始化;
  • 如有必要,更新f_op指针;
  • 分配并填写至于filp->private_data里的数据结构;

2. write()系统调用

/**
 * @brief write函数原型之一
 * @param[*filp] 文件指针
 * @param[*buff] 指向用户空间缓冲区
 * @param[count] 请求传输的数据长度
 * @param[*offp] 指向“long offset type(长偏移量类型)”对象指针,指明用户在文件中进行存取操作的位置。
 * @retval signed size type(有符号的尺寸类型)
 */
ssize_t write(struct file *filp, const char _ _user *buff, size_t count, loff_t *offp);

参考《LINUX设备驱动程序》-第六章:
如果open()文件是没指定O_NONBLOCK或O_NDELAY则默认是阻塞的。进程会进入休眠状态。
如果open()文件指定O_NONBLOCK或O_NDELAY,则write()操作文件不会阻塞,当文件无数据时直接返回-EAGAIN。

2.1 write()返回值

  • 如果返回值等于count,则完成了所请求数目的字节传送;
  • 如果返回值是正的,但小于count,则只传输了部分数据。程序很可能再次试图写入余下的数据。
  • 如果为0,意味着什么也没写入。这个结果不是错误,而且也没有理由返回一个错误码。标准库会重复调用write。在介绍阻塞式write内容中有详细说明。
  • 负值意味发生了错误,有效的错误码定义在linux/errno.h中;
  • 如果write的缓冲区没有空间,则有阻塞和非阻塞两种情况(由open()时的参数决定)。非阻塞时返回-EAGAIN。

3. read()系统调用

/**
 * @brief read函数原型之一
 * @param[*filp] 文件指针
 * @param[*buff] 指向用户空间缓冲区
 * @param[count] 请求传输的数据长度
 * @param[*offp] 指向“long offset type(长偏移量类型)”对象指针,指明用户在文件中进行存取操作的位置。
 * @retval signed size type(有符号的尺寸类型)
 */
ssize_t read(struct file *filp, char _ _user *buff, size_t count, loff_t *offp);

参考《LINUX设备驱动程序》-第六章:
如果open()文件是没指定O_NONBLOCK或O_NDELAY则默认是阻塞的。进程会进入休眠状态。
如果open()文件指定O_NONBLOCK或O_NDELAY,则read()操作文件不会阻塞,当文件无数据时直接返回-EAGAIN。

3.1 read()的返回值

  • 返回值等于count参数,说明所请求的字节数传输成功完成。最理想的情况。
  • 返回值是正,但比count小,说明只有部分数据成功传送。该情况因设备不同可能有许多原因。大部分情况下,程序会重新读数据。
    例如,如果用fread函数读数据,这个库函数就会不断的调用系统调用,直至所请求的数据传输完毕为止。
  • 返回值为0,则表示已经到达文件尾。
  • 负值意味着发生了错误,该值指明了发生的具体错误,错误码在linux/errno.h中定义。如:-EINTR(系统调用被中断),-EFAULT(无效地址)。
  • 假如当前文件没有数据可读,则有阻塞和非阻塞两种情况(由open()时的参数决定)。非阻塞时返回-EAGAIN。

参考

  • 《LINUX设备驱动程序》
  • 《深入理解LINUX内核》
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值