Linux 学习笔记:文件I/O 基础

一、文件描述符

1.1 文件描述符介绍

当调用open 函数打开一个现有文件或创建一个新文件时,内核会向进程返回一个文件描述符,用于指代被打开的文件,所有执行IO操作的系统调用都是通过文件描述符来索引对应的文件。在C代码中,文件描述符是一个int 类型变量。

1.2 进程最大文件数

在Linux 中,一个进程可以打开的文件数是有限制的,可以通过命令ulimit 来查看进程可打开的最大文件数,用法如下:
ulimit -n
这里最大值默认是1024.

1.3 三个特殊文件描述符

文件描述符具体文件
0系统标准输入(一般指键盘)
1系统标准输出 (一般指LCD显示器)
2系统标准错误 (一般指LCD 显示器)
所以,我们程序中调用open函数打开文件的时候,分配的文件描述符一般都是从3开始。

二、常见文件IO函数

2.1 open

在Linux 系统中要操作一个文件,需要先打开该文件,得到文件描述符,然后再对文件进行相应的读写操作,最后再关闭该文件。当打开的文件不存在时,可以配置创建一个新的文件,open 函数原型如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

2.1.1 函数参数以及返回值

2.1.1.1 pathname

字符串类型,用于标识需要打开或创建的文件,可以包含路径信息。例如: ./test_file

2.1.1.2 flags

调用open 函数时需要提供的标志,包括文件访问模式标志以及其它文件相关标志,这些标志使用宏定义进行描述,都是常量。我们传入的flags 参数既可以单独使用某一个标志,也可以通过位或运算(|)将多个标志进行组合。open 函数的第三个参数,只有在使用了O_CREATO_TMPFILE 标志时才有效。 常见标志介绍如下:

文件访问方式标志
  • O_RDONLY 以只读方式打开文件
  • O_WRONLY 以只写方式打开文件
  • O_RDWR 以可读可写方式打开文件
    这三个是文件打开方式标志,传入的flags 参数中必须要包含其中一种标志,而且只能包含一种。
标志用途说明
O_CREAT如果pathname参数指向的文件不存在则创建此文件使用此标志时,调用open函数需要传入第三个参数mode,参数mode用于指定新建文件的访问权限。
O_DIRECTORY如果pathname 参数指向的不是一个目录,则调用open失败
O_EXCL此标志一般结合O_CREAT 标志一起使用,用于专门创建文件。在flags 参数同时使用到了O_CREAT 和O_EXCL 标志的情况下,如果pathname 参数指向的文件已经存在,则open函数返回错误可以用于测试一个文件是否存在,如果不存在则创建此文件,如果存在则返回错误。这使得测试和创建两者成为一个原子操作。
O_NOFOLLOW如果pathname 参数指向的是一个符合链接,将不对其进行解引用,直接返回错误不加此标志情况下,如果pathname 参数是一个符合链接,会对其进行解引用
不同内核版本所支持的flags 标志是存在差异的。例如说新版本内核所支持的标志可能老版本就不支持的,亦或者老版本支持的标志在新版本已经被取消、替代,man手册中对一些标志是从哪个版本开始支持的有简单地说明。
2.1.1.3 mode
宏定义说明
S_IRUSR允许文件所有者读文件
S_IWUSR允许文件所有者写文件
S_IXUSR允许文件所有者执行文件
S_IRWXU允许文件所有者读写执行文件
S_IRGRP允许同组用户读文件
S_IWGRP允许同组用户写文件
S_IXGRP允许同组用户执行文件
S_IRWXG允许同组用户读、写、执行文件
S_IROTH允许其他用户读文件
S_IWOTH允许其他用户执行文件
S_IXOTH允许其他用户执行文件
S_IRWXO允许其他用户读、写、执行文件

2.2 read

调用read 函数可从打开的文件中读取数据。

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

函数参数和返回值含义如下:

  • fd : 文件描述符
  • buf:指定读入数据对应的缓冲区。
  • count:指定需要读取的字节数。
  • 返回值:如果读取成功将返回读取到的字节数,实际读取到的字节数可能会小于count参数指定的字节数,也有可能会为0,例如进行读操作时,当前文件偏移量已经到了文件末尾。实际读取到的字节数小于要求读取的字节数,例如在到达文件末尾之前有30个字节数据,而要求读取100个字节,则read读取成功只能返回30;而再次再调用read读,它将返回0(文件末尾)。

2.3 write

调用write 函数可向打开的文件写入数据,其函数原型如下:


#include <unistd.h>

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

函数参数和返回值:

  • fd : 文件描述符
  • buf:指定写入数据对应的缓冲区。
  • 返回值:如果成功将返回写入的字节数(0 表示未写入任何字节);如果此数字小于count 参数,这不是错误,可能是磁盘空间已满。如果返回-1,表示写入出错。

2.4 close

可调用close 函数关闭一个已经打开的文件。

#include <unistd.h>
int close(int fd);

函数参数和返回值:

  • fd : 需要关闭的文件的描述符。
  • 返回值:成功返回0;失败返回-1;在Linux 系统中,当一个进程终止时,内核会自动关闭它打开的所有文件。

2.5 lseek

对于每个打开的文件,系统都会记录它的读写位置偏移量,当调用read()或write 函数对文件进行读写操作时,就会从当前读写位置偏移量开始进行数据读写。当打开文件时,会将读写偏移量设置为指向文件开始位置处,以后每次调用read()、write()会自动对其进行调整,以指向已读或已写数据后的下一个字节。

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

函数参数和返回值

  • fd : 文件描述符
  • offset : 偏移量,以字节为单位。
  • whence:用于定义参数offset 偏移量对应的参考值。该参数为下列其中一种:
参数说明
SEEK_SET读写偏移量将指向offset 字节位置处(从文件头部开始算)
SEEK_CUR读写偏移量将指向当前位置偏移量+offset 字节位置处,offset 可以为正、也可以为负,如果是正数表示往后偏移,如果是负数则表示往前偏移
SEEK_END读写偏移量将指向末尾 + offset 字节位置处,offset 可以为正,也可以为负。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gdut_llkkyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值