标准C库函数 和 Linxu系统IO函数 open和close 虚拟地址空间

C库的IO函数

C库函数通过  FILE指针  来访问文件并索引到对应磁盘文件,
FILE文件指针(结构体)
  文件描述符:定位文件 
  文件读写指针:对数据进行操作 读写指针
  缓冲区:提高效率
FILE 是  _IO_FILE   的重定义
复制代码
 1 struct _IO_FILE
 2 {
 3   int _flags;        /* High-order word is _IO_MAGIC; rest is flags. */
 4 
 5   /* The following pointers correspond to the C++ streambuf protocol. */
 6   char *_IO_read_ptr;    /* Current read pointer */    //读指针
 7   char *_IO_read_end;    /* End of get area. */
 8   char *_IO_read_base;    /* Start of putback+get area. */
 9   char *_IO_write_base;    /* Start of put area. */
10   char *_IO_write_ptr;    /* Current put pointer. */    //写指针
11   char *_IO_write_end;    /* End of put area. */
12   char *_IO_buf_base;    /* Start of reserve area. */    //缓冲区起始
13   char *_IO_buf_end;    /* End of reserve area. */     //缓冲区结束 
14 
15   /* The following fields are used to support backing up and undo. */
16   char *_IO_save_base; /* Pointer to start of non-current get area. */
17   char *_IO_backup_base;  /* Pointer to first valid character of backup area */
18   char *_IO_save_end; /* Pointer to end of non-current get area. */
19 
20   struct _IO_marker *_markers;
21 
22   struct _IO_FILE *_chain;
23 
24   int _fileno;//文件描述符    标准C库的IO函数调用会调用Linux系统的IO函数,系统IO函数会返回一个文件描述符fd标识,标准C库得到fd赋给 _fileno 通过fd文件描述符的值获取文件位置
25   int _flags2;
26   __off_t _old_offset; /* This used to be _offset but it's too small.  */
27 
28   /* 1+column number of pbase(); 0 is unknown. */
29   unsigned short _cur_column;
30   signed char _vtable_offset;
31   char _shortbuf[1];
32 
33   _IO_lock_t *_lock;
34 #ifdef _IO_USE_OLD_IO_FILE
35 };
复制代码
标准 C 库 IO 和 Linux 系统 IO 的关系

虚拟地址空间  :解决程序加载内存的问题,解决堆、栈的问题

虚拟地址空间是不存在的,是虚拟的想象中的空间,  32位开辟的虚拟地址空间一般位2^32(4GB)  64位开辟的虚拟地址空间一般位2^48。

以4G为例:最多为4G但是理想状态,实际用不到4G,堆空间为  低地址向高地址存储, 栈空间为高地址往低地址存储

内核区:用户无读写权限,想要操作内核数据,需要进行系统调用,调用Linux系统的API函数

 文件描述符  

  程序:不占用内存空间,仅占用磁盘空间

  进程(正在运行的程序):操作系统创建,给运行的程序分配的一些资源,占用内存空间,启动后有虚拟地址空间,通过CPU中MMU逻辑管理单元,将虚拟地址空间中数据映射到物理内存中

  文件描述符:在进程的内核区,(Linux内核就是一个程序,PCB进程控制块是一个复杂的结构体),结构体中有一个数组,即文件描述符表(文件描述符表,表中每个文件描述符都对应一个文件),默认大小为1024,同时能打开的最多文件数为1024个。

  文件描述符表:前三位默认占用:标准输入,标准输出,标准错误,且默认打开,对应于当前使用的终端。

open函数和close函数  

复制代码
 1 /*
 2     #include <sys/types.h>
 3     #include <sys/stat.h>
 4     #include <fcntl.h>
 5     //多个头文件 是因为open函数中多个参数在不同头文件中,调用的时候按需使用
 6     //打开一个存在的文件
 7     int open(const char* pathname, int flags);
 8         参数:
 9             - pathname:要打开的文件路径
10             - flags:对文件的操作权限设置还有其他的设置
11             O_RDONLY, O_WRONLY, O_RDWR 这三个设置是互斥的
12         返回值: 返回一个新的文件描述符,如果调用失败,返回 -1
13     
14     errno:属于Linux系统函数库,库里面的一个全局变量,记录的是最近的错误号
15     #include <stdio.h>
16     void perror(const char* s)
17         作用:打印errno对应的错误描述
18         s参数:用户描述,比如hello,最终输出的内容是 hello:xxx(实际的错误描述)
19 
20     //创建一个新的文件
21     int open(const char* pathname, int flags,mode_t mode);
22 */
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <stdio.h>      //perror函数
27 #include <unistd.h>     //close函数
28 int main()
29 {
30     int fd = open("a.txt",O_RDONLY);//fd文件描述符:file descriptor
31     if(fd == -1)
32     {
33         perror("open");//打印  open:具体错误原因
34         //open:No such file or directory
35     }
36     //关闭
37     close(fd);
38     return 0;
39 }
复制代码

未创建  a.txt  文件前,输出错误

 rwx三个一组: 当前文件权限,所在组文件权限,其他文件权限  

  r:读取    w:写    x:可执行权限

umask:0002(普通用户)(不同用户的umask值不同)  root用户(0022)
umask  022  将umask设置为 0022(仅在当前终端有效) 
  例如:设置权限最高为0777(八进制)  但是根据     最终的权限: mode & ~umask  普通用户的设定umask为(0002)   结果为0775 其他文件权限降低

复制代码
 1 /*
 2     #include <sys/types.h>
 3     #include <sys/stat.h>
 4     #include <fcntl.h>
 5 
 6     //创建一个新的文件
 7     int open(const char* pathname, int flags,mode_t mode);
 8     参数:
 9         - pathname:要创建的文件路径
10         - flags:对文件的操作权限和其他设置
11                 - 必选项: O_RDONLY,  O_WRONLY,  O_RDWR   互斥 三选一
12                 - 可选项: O_CREAT 文件不存在,创建新文件 
13         - mode:八进制的数,表示创建出新文件的操作权限 
14         最终的权限是:  mode & ~umask
15         umask:0002(普通用户)(不同用户的umask值不同)  root用户(0022)  
16         0002取反(~umask)   0775
17         0777(111 111 111) & 0775(111 111 101)
18         按位与(0与任何书都为0)---> 111111101   0775 
19         umask作用就是抹去 某些权限   
20         
21         int fd = open("create.txt",O_RDWR | O_CREAT,0777);  为什么用  | (按位或)   
22         flags参数是一个 int类型的数据 占4个字节, 32位
23         flags  32个位,每一个就是一个标志位
24         第几位:  1--R   2--W  3--RW  4--CREATE
25 */
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <stdio.h>      //perror函数
30 #include <unistd.h>     //close函数
31 
32 int main()
33 {
34     //创建一个新的文件
35     int fd = open("create.txt",O_RDWR | O_CREAT,0777);//键入0777 由于普通用户umask 结果为0775
36 
37     if(fd == -1)
38     {
39         perror("open");
40     }
41     //关闭
42     close(fd);
43     return 0;
44 }
复制代码

posted on   廿陆  阅读(24)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示