系统调用接口操作io和文件描述符详解

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

我在只前的博客已经写了在C语言库的一些输入输出操作接口,标准C库的文件io操作接口,现在让我们再来看一下系统调用接口吧。

系统调用接口和C库操作的关系

在我们编写代码时,时不时经常用到库里面的一些函数来帮助我们完成功能,那那些C库里的操作又是依赖什么完成的呢?
C库的函数实际上就是对系统调用接口的封装,C库就是调用系统接口实现的。

系统调用常见操作

打开操作

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
//pathname是要打开的文件名称,flag是标志信息,mode当文件创建时指定权限

1.我们看两个open就知道mode是非必要选项,就是说,可以给参,也可以不给参数。
2.flag 要求我们指出是以何种权限打开文件,像r,r+,等,falg也有它对应的选择项。
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
还有可以与上述组合使用的
O_CREAT 存在打开,不存在创建
O_EXCL 与O_CREAT同时使用表示,不存在则报错
O_TRUNC 文件存在则截断为0
O_APPEND 写入时在文件末尾追加
3.mode选项,之所以可以给可以不给,因为我们创建文件的时候有默认的权限,umask()可以设置权限掩码。注意:mode这是权限码,要以0开头,例如0664,否则会出错。
4.返回值,正确返回文件描述符,失败返回-1

写入,读取操作

//写入
ssize_t write(int fd, const void *buf, size_t count);
//fd则是我们说的文件标识符,buf我们要写入的字符串,count字符串大小。
//读取
ssize_t read(int fd, void *buf, size_t count);

移动位置操作

off_t lseek(int fd, off_t offset, int whence);
//fd文件标识符,offset偏移量,whence基址位置。类似与C库中的fseek:

下面我们来举例使用一下这些操作

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<fcntl.h>
  4 #include<string.h>
  5 #include<errno.h>
  6 int main()
  7 {
  8     int fd;
  9     fd=open("./test.txt",O_RDWR | O_CREAT| O_APPEND ,0666);//默认还有-umask,及-002
 10     if(fd<0)
 11     {
 12         perror("open error");
 13         return -1;
 14     }
 15     char buff[1024]="hello world!\n";
 16     ssize_t w_len = write(fd,buff,strlen(buff));
 17     if(w_len < 0)
 18     {
 19         perror("write error");
 20         return -1;
 21     }
 22     lseek(fd,0,SEEK_SET);
 23     printf("real write len :[%d]%s\n",w_len,buff);
 24     char ptr[1024]={0};
 25     ssize_t r_len = read(fd, ptr,1024-1);
 26     if(r_len<0)
 27     {
 28         perror("read error");
 29         return -1;
 30     }
 31     printf("read len:[%d]  %s\n",r_len,ptr);
 32     close(fd);
 33     return 0;
 34 }

运行结果如下:
这里写图片描述

什么是文件标识符?

文件标识符类似与windows平台下的句柄,它就像系统给你的独一无二的代号,通过代号系统可以找到你。
一个进程中会打开很多文件,进程需要通过结构体管理这些文件而每一个结构体中都有一个文件标识符及inode节点,它可以唯一表示这个文件。
这个innode节点实际上就是一个整数,它是文件描述信息结构体数组的下标,通过这些下标来找到文件。
注意:
1.因为inode节点数其实是数组下标,是数组大小必定有限,所以才会要求我们打开文件后一定记得关闭。
2.文件下标分配规则:优先使用最小的下标

常见文件描述符

stdin inode=0 标准输入
stdout inode=1 标准输出
sterr inode=2 标准错误输出

对比文件描述符和文件流指针

文件流指针的应用范畴是库函数中的io操作,C语言中使用文件流指针作为IO句柄,来标识文件。
1.文件流指针读写文件经过缓冲区,可以把数据逐一加载到缓冲区后,一起操作,提高效率。
而文件标识符对应的系统调用是不经过缓冲区的,而是直接操作。
2.文件流指针的结构体中国包含有文件描述符。

猜你喜欢

转载自blog.csdn.net/weixin_40921797/article/details/81979670