通用I/O

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vrg000/article/details/78180647

Linux文件类型

普通文件(-)
目录(d)
字符设备(c)
块设备(b)
套接字(s)
管道(p)
符号链接(l)

在Linux中,几乎所有概念都可以抽象成一个文件
一共七种文件类型,均可以使用通用I/O进行操作。

文件描述符

用于指代一个打开的文件,是一个正整数。

标准文件描述符

文件描述符 用途 POSIX名称
0 标准输入 STDIN_FILENO
1 标准输出 STDOUT_FILENO
2 标准错误 STDERR_FILENO

标准I/O操作

# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>

int open(const char *pathname, int flags, .../*mode_t mode*/);  //打开文件
int creat(const char *pathname, mode_t mode);  //创建文件
ssize_t read(int fd, void *buffer, size_t count);    //读文件
ssize_t write(int fd, void *buffer, size_t count);  //写文件
int close(int fd);   //关闭文件
off_t lseek(int fd, int offset, int whence);  //修改偏移量
int ioctl(int fd, int request, .../*argp*/);  //I/0控制

open():打开文件

int open(const char *pathname, int flags);
  • int 返回值:成功返回文件描述符,失败返回-1并设置errno
  • const char *pathname:文件名
    • 如果文件名所指代的文件是一个符号链接,则对符号链接进行解引用
  • int flags:选项
    • O_RDONLY:以只读的方式打开文件
    • O_WRONLY:以只写的方式打开文件
    • O_RDWR:以读写的方式打开文件
      :以上3个选项为必选选项,3选1
    • O_APPEND:在文件尾部追加数据
    • O_ASYNC:当文件描述符可以进行I/O操作时,系统返回一个信号通知进程。这种操作被称为信号驱动I/O,仅对特定类型文件有效(终端设备、管道,套接字)。该标志对Linux无效(大多数UNIX中有与之等效的FASYNC标志),在Linux中必须通过fcntl()的F_SETFL来设置O_ASYNC标志
    • O_CLOEXEC:启用close-on-flag标志,fork()后调用execve()时,会关闭用close-on-flag标志修饰的文件描述符。这样做可以防止文件描述符泄露给其他程序。(Linux 2.6.23开始支持)
    • O_CREAT:如果文件不存在,则创建文件,使用该选项需要提供mode参数
    • O_DIRECT:无缓冲I/O:需要定义功能测试宏_GNU_SOURCE才能使用
    • O_DIRECTORY:如果pathname参数不是目录,返回错误,errno为ENOTDIR,需要定义功能测试宏_GNU_SOURCE才能使用
    • O_DSYNC:每次write都等待物理I/O完成,但是如果写操作不影响读取刚写入的数据,则不等待文件属性更新(Linux 2.6.33开始支持)
    • O_EXCL:和O_CREAT一起使用,如果文件已存在,则返回错误,用于测试文件是否存在
    • O_LARGEFILE:打开大文件(超过4G的文件),在32位系统中有效
    • O_NOATIME:读文件时,不更新文件的最近访问时间,可提高性能(Linux 2.6.8开始支持)
    • O_NOCTTY:防止设备称为控制终端,以防键盘输入影响到进程。
    • O_NOFOLLOW:如果pathname是符号链接,则打开符号链接,不对其进行解引用,需要定义功能测试宏_GNU_SOURCE才能使用
    • O_NONBLOCK:非阻塞方式打开文件
    • O_SYNC:每次write都等待物理I/O操作完成,包括对文件的属性更新。
    • O_TRUNC:如果文件已存在,清空文件
  • …/mode_t mode/:文件的属性,O_CREAT时才会使用
权限 作用
S_IRWXU 00700 用户读写执行
S_IRUSR 00400 用户读
S_IWUSR 00200 用户写
S_IXUSR 00100 用户执行
S_IRWXG 00070 组读写执行
S_IRGRP 00040 组读
S_IWGRP 00020 组写
S_IXGRP 00010 组执行
S_IRWXO 00007 其他读写执行
S_IROTH 00004 其他读
S_IWOTH 00002 其他写
S_IXOTH 00001 其他执行

* 三种特殊权限
* S_ISUID:04000:用于修饰可执行权限,让调用者拥有可执行文件的拥有者的用户权限
* S_ISGID:02000:用于修饰可执行权限,让调用者拥有可执行文件的拥有者的组权限
* S_ISVTX:01000:作用1:修饰可执行程序,可执行程序执行完成后,会在swap缓存,由于swap时连续的,读取速度比磁盘快,可用于程序快速启动。作用2:在/tmp目录下可以创建自己的文件,但不能删除别人的文件。

create():创建文件

int creat(const char *pathname, mode_t mode);  //创建文件
  • int 返回值:成功返回0,失败返回-1并设置errno
  • const char *pathname:文件名
  • mode_t mode:文件属性,同open()的第三个参数相同

read():读取文件

ssize_t read(int fd, void *buffer, size_t count);    //读文件
  • ssize_t返回值:成功返回实际读取字节数,失败返回-1并设置errno,针对不同的文件类型,会有不同的出错返回值以及处理方式,这里不进行详述
  • int fd:文件描述符
  • void *buffer:缓冲区
  • size_t count:请求读取字节数(实际读取字节可能小于请求读取字节)
    :请求读取字节不能大于缓冲区大小

write():写入文件

ssize_t write(int fd, void *buffer, size_t count);  //写文件
  • ssize_t返回值:成功返回实际写入字节数,失败返回-1并设置errno,针对不同的文件类型,会有不同的出错返回值以及处理方式,这里不进行详述
  • int fd:文件描述符
  • void *buffer:缓冲区
  • size_t count:请求写入的字节数(实际写入字节可能小于请求写入字节)
    :请求写入字节数不能大于缓冲区大小

close():关闭文件

int close(int fd);   //关闭文件
  • int返回值:成功返回0,失败返回-1并设置errno
  • int fd:文件描述符

lseek():修改偏移量

每个文件都有一个文件偏移量指针,指向当前写入文件的位置,read()、write()操作会自动更改文件偏移量指针的位置。可使用lseek()手动调整指针的位置。当指针指向一块没有实际内容的文件时(指针超出文件的尾部)会形成空洞文件。

空洞文件的空洞部分几乎不占用任何空间(存储空洞信息会占用空间,但不一定会分配新的磁盘块),读取空洞文件时,空洞部分会以0填充。

off_t lseek(int fd, int offset, int whence);  //修改偏移量
  • off_t返回值:返回当前文件偏移量指针
  • int fd:文件描述符
  • int offset:偏移量,可为0,表示当前位置;可为正,表示向后;可为负,表示向前
  • int whence:参考位置
位置 解释
SEEK_SET 0 从0开始
SEEK_CUR 1 从当前偏移量开始
SEEK_END 2 从文件尾部的下一个字节开始

ioctl():I/O控制

int ioctl(int fd, int request, .../*argp*/);  //I/0控制
  • int返回值:成功返回0,失败返回-1并设置errno
  • int fd:文件描述符
  • int request:请求类型,不同的请求类型会有不同的argp参数
  • :argp参数
    :针对不同的文件类型,会有不同的请求类型,这里不进行详述

通用I/O中的多态

强调一下,任何类型的文件,都以文件描述符为句柄,针对不同的文件类型,通用I/O会做出不同的操作(调用不同的函数),此为通用I/O的多态。

文件描述符,打开文件表,i-node之间的关系

图1

  • 每个进程都有PCB,PCB中包含文件描述符表
  • 内核有打开文件表,用于存储系统中所有打开的文件
  • 内核有i-node表,用于描述文件实际存储的位置

猜你喜欢

转载自blog.csdn.net/vrg000/article/details/78180647
I/O