新能源网站开发,十大软件开发培训机构,木材网站建设哪家好,网站建设微信公众号需要掌握#xff1a;操作文件#xff0c;本质#xff1a;进程操作文件。进程和文件的关系 向文件中写入#xff0c;本质上向硬件中写入-用户没有权利直接写入-操作系统是硬件的管理者#xff0c;我们可以通过操作系统往硬件写入-操作系统必须提供系统调用操作文件本质进程操作文件。进程和文件的关系 向文件中写入本质上向硬件中写入-用户·没有权利直接写入-操作系统是硬件的管理者我们可以通过操作系统往硬件写入-操作系统必须提供系统调用默认操作系统不相信任何人 我们使用的fopen/fwrite/fread/fprintf/scanf/printf/cin/cout/实际上都是对系统调用的接口的封装.
系统调用函数open
头文件 #include sys/types.h#include sys/stat.h#include fcntl.h
open函数 int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);
第一个open函数的第一个参数是文件名第二个参数是打开方式 其中我们要了解的打开方式有 O_WRONLY//只读方式O_CREAT//没有该文件就创建O_APPEND//追加O_TRUNC//覆盖式写入
因为要用到close函数关闭文件 close函数
头文件
#include unistd.hint close(int fd);有一个疑问为什么他的 参数是int类型的因为对应的打开方式可以是int 32中任何一位为1并且和其他区分开来然后需要多个功能的话按位或就可以这是操作系统调用接口的常见方法
1.只写和没有该文件就创建 1 #includestdio.h2 #include sys/types.h3 #include sys/stat.h4 #include fcntl.h5 #include unistd.h6 int main()7 {8 int fdopen(log.txt, O_WRONLY| O_CREAT|O_APPEND); 9 if(fd0)10 {perror(open);11 return 1;}12 close(fd);13 return 0;14 15 } O_WRONLY| O_CREAT我们发现当前目录下没有我们要的“log.txt” 当我们运行这个程序后发现出现了该文件 为了测试追加功能我们通过vim往log.txt里面写入点东西
修改打开方式为只写和追加所以修改参数2为 O_WRONLY|O_APPEND但是我们发现log.txt这个文件的权限怎么不对呀这里是因为如过用第一个open函数的话就必须是已经创建好的文件就已经有了权限要不然就只能用第二个open函数第二个open函数的第三个参数就是要设置的掩码值所以我们使用第二个open函数 #includestdio.h2 #include sys/types.h3 #include sys/stat.h4 #include fcntl.h5 #include unistd.h6 int main()7 {8 int fdopen(loog.txt, O_WRONLY| O_CREAT|O_APPEND,0666); //设置log.txt文件掩码为0666 9 if(fd0)10 {perror(open);11 return 1;}12 close(fd);13 return 0;14 15 } 但是这里的权限是664呢因为我们可以通过unmask来查看对应的默认掩码
我们可以将默认掩码在函数内设置为0 这段代码修改了掩码为0并且修改其文件名 此时我们就可以修改我们的loog.txt文本文件了
使用打开方式 O_WRONLY|O_APPEND此时我们就用到了write函数
头文件
#include unistd.h
函数 ssize_t write(int fd, const void *buf, size_t count);
函数第一个参数是文件描述符对应你打开的文件待会在讲这个fd,文件描述符 第二个参数是你要写入的字符串第三个参数是要写入字符串的大小 1 #includestdio.h 2 #include sys/types.h 3 #include sys/stat.h 4 #include fcntl.h 5 #include unistd.h 6 int main() 7 { 8 umask(0); 9 10 int fdopen(looog.txt, O_WRONLY|O_APPEND,0666); 11 12 if(fd0) 13 {perror(open); 14 return 1;} 15 char buf[]hello world; 16 write(fd, buf,sizeof(buf)); 17 close(fd); 18 return 0; 19 20 } 覆盖式写入
第二个参数修改为 O_WRONLY| O_TRUNC1 #includestdio.h2 #include sys/types.h3 #include sys/stat.h4 #include fcntl.h5 #include unistd.h6 int main()7 {8 umask(0);9 10 int fdopen(looog.txt, O_WRONLY| O_TRUNC,0666); 11 12 if(fd0) 13 {perror(open); 14 return 1;} 15 char buf[]hello world; 16 write(fd, buf,sizeof(buf)); 17 close(fd); 18 return 0; 19 20 } 除了上面的方法给文件写入数据我们还可以通过echo写入数据 我们发现是覆盖式写入 我们发现是追加式写入 文件操作符
我们刚才使用了open函数和write函数里面open函数返回的是一个fd,write的第一个参数是fd,这就是我们要提到的文件操作符 为了讲清文件操作符这个概念 我们可以先来说说操作系统是如何进行文件的写入和读呢
在我们启动进程时默认操作系统已经帮我们打开 标准输入流0对应的文件标识符—键盘 标准输出流1对应的文件标识符—显示器 标准错误流2对应的文件标识符—显示器 我们可以把这些外设也当成文件linux一切皆文件 如果是文件当我们使用的时候也会给他创建pcb结构来管理外设 在操作系统内系统在访问文件的时候只认文件描述符fd open函数在干什么呢 1.创建file对应的pcb管理文件属性 2.开辟文件缓冲区的空间将文件数据加载到文件缓冲区去延后 3.查进程文件的文件描述表 4.将对应文件的地址填入到指针数组中去 5.返回下标
文件操作符的本质是什么呢 内核的进程文件映射关系的数组下标
c语言如何通过FILE*访问文件呢 1 #includestdio.h2 int main()3 {4 FILE* fpfopen(hot.txt,w);5 if(NULLfp)6 {7 perror(fopen error);8 return 1;9 10 11 12 }13 fprintf(fp,hello world);14 fclose(fp);15 return 0; 16 }
实际上FILE是一个c语言的一个结构体类型里面封装了文件标识符fd
gcc -E file.c -o file.i//预处理完就停下头文件展开
在stdio.h头文件里面 1 #includestdio.h2 int main()3 {4 printf(输入流:%d\n,stdin-_fileno);//对应结构体里面封装了文件的文件标识符5 printf(输出流:%d\n,stdout-_fileno);6 printf(错误流:%d\n,stderr-_fileno); 7 8 9 10 11 12 13 14 15 }
接着打开的文件的文件标识符就从3开始往后 终端也是文件 我们复制ssh的渠道左边为另一个终端 1 #includestdio.h2 #include unistd.h3 #include sys/types.h4 #include sys/types.h5 #include sys/stat.h6 #include fcntl.h7 8 int main()9 {10 while(1)11 {12 printf(pid:%d\n,getpid());13 14 15 16 17 18 } 19 //int fdopen(/dev/pts/0,O_WRONLY| O_TRUNC,0666);20 //if(fd0) 21 // {perror(error);} 22 //char arr[]hello wokao; 23 //write(fd,arr,sizeof(arr)); 24 //close(fd); 25 26 }/proc/目录下存在着正在运行的进程的pid
1 #includestdio.h2 #include unistd.h3 #include sys/types.h4 #include sys/types.h5 #include sys/stat.h6 #include fcntl.h7 8 int main()9 {int fdopen(/dev/pts/0,O_WRONLY| O_TRUNC,0666);10 if(fd0)11 {perror(error);}12 char arr[]hello wokao;13 write(fd,arr,sizeof(arr));14 close(fd);15 16 } 把终端当文件写入 c语言为什么支持跨平台性
支持系统调用也可以使用语言提供文件方法系统不同可能导致系统调用的接口可能不一样导致代码不具有跨平台性所以所有的语言都想具有跨平台性所以所有的语言要对平台的系统调用进行封装不同语言封装文件接口就有差别了