系统调用----初步了解文件描述符
2018-03-27 22:34
309 查看
在学习操作系统之前,我们在操作文件时会使用一些C接口,比如说,fwrite fread fopen fclose 这些,但是除了这些C接口(其他语言也有),我们还可以使用一些系统调用接口来进行文件访问。
例如:
写文件(write)
代码实现:
读文件(read)
代码实现:
之前我们使用C接口操作文件是总会用到 FILE* ,而现在我们使用系统调用接口发现有一个自称是文件描述符的 fd 。下面我们就来说一说这个文件描述符。
文件描述符:是一个取值为0,1,2,3,4,5,6,7,8,,9,10……的数(没有负值)
另外,我们的C总是默认打开3个输入输出流,分别是:
三者分别对应于我们的键盘,显示器,显示器。
这三个流的类型都是FILE*,也就是说他们的返回值类型都是文件指针。
回到文件描述符来说,这三个对应的文件描述符分别是:
Linux进程默认这3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2。
当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件,于是就有了file结构体,表示一个已经打开的文件对象,而进程执行open系统调用,所以必须让进程和文件关联起来,每个进程都有一个指针*files,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针,所以,本质上,文件描述符就是该数组的下标,所以只要拿着文件描述符,就可以找到对应的文件。
对于新打开的文件的文件描述符的分配规则就是:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。
IO相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是通过fd访问的,所以说C库当中的FILE结构体内部,必定封装了fd。
例如:
写文件(write)
代码实现:
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<string.h> #include<unistd.h> //往名为“myfile”的文件里写入5条hello,world int main() { umask(0); //fd为文件描述符 //O_WRONLY:只写,O_CREATE:如果想要打开的文件不存在则创建该文件 //0644:权限 int fd = open("myfile",O_WRONLY|O_CREAT,0644); if(fd < 0) { perror("open"); return 1; } int count = 5; const char *msg = "hello,world\n"; int len = strlen(msg); while(count--) { //fd:文件描述符 //msg:缓冲区首地址 //len:本次读取,期望写入多少个字节的数据 //返回值:实际写了多少字节的数据 write(fd,msg,len); } close(fd); return 0; }
读文件(read)
代码实现:
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #include<string.h> //往buf里读入5个 int main() { //O_RDONLY:只读 int fd = open("myfile",O_RDONLY); if(fd < 0) { perror("open"); return 1; } int count = 5; const char *msg = "hello,world\n"; char buf[1024]; while(count--) { //fd:文件描述符 //buf:指定内存 //strlen(msg):一次读取这么多字节 //返回值:返回0表示已到达文件尾或是无可读取的数据 //返回非0的正数则为实际读取到的字节数 ssize_t s = read(fd,buf,strlen(msg)); if(s > 0) { printf("%s",buf); } else { break; } } close(fd); return 0; }
之前我们使用C接口操作文件是总会用到 FILE* ,而现在我们使用系统调用接口发现有一个自称是文件描述符的 fd 。下面我们就来说一说这个文件描述符。
文件描述符:是一个取值为0,1,2,3,4,5,6,7,8,,9,10……的数(没有负值)
另外,我们的C总是默认打开3个输入输出流,分别是:
stdin:标准输入 stdout:标准输出 stderr:标准错误
三者分别对应于我们的键盘,显示器,显示器。
这三个流的类型都是FILE*,也就是说他们的返回值类型都是文件指针。
回到文件描述符来说,这三个对应的文件描述符分别是:
stdin->0 stdout->1 stderr->2
Linux进程默认这3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2。
当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件,于是就有了file结构体,表示一个已经打开的文件对象,而进程执行open系统调用,所以必须让进程和文件关联起来,每个进程都有一个指针*files,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针,所以,本质上,文件描述符就是该数组的下标,所以只要拿着文件描述符,就可以找到对应的文件。
对于新打开的文件的文件描述符的分配规则就是:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。
IO相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是通过fd访问的,所以说C库当中的FILE结构体内部,必定封装了fd。
相关文章推荐
- 应用中调用系统的搜索UI,Android Search Framework的初步了解
- 短文了解系统dubbo客户端通过zk调用另一个系统的dubbo服务端
- windows 64位系统初步了解
- 初步了解《css》和《skin》调用
- iOS&OSX系统初步了解
- 初步探讨Zigbee之详细了解系统时钟(+电源管理)
- 系统调用初步
- 【学生信息管理系统 1】:初步了解,整体规划
- 了解 TCP 系统调用序列
- 【学生信息管理系统 1】:初步了解,整体规划
- linux 文件系统构建之初步了解yaffs
- windows 64位系统初步了解
- QNX分布式实时操作系统初步认识-QNX系统了解认识
- 了解 TCP 系统调用序列
- 初步了解在线测试系统
- 了解 TCP 系统调用序列
- 以调用系统相机拍照为例了解Android 6.0运行时权限
- Pin截获socket系统调用初步分析
- [学]USB学习笔记 第一篇 初步了解USB系统
- 了解 TCP 系统调用序列