当前位置: 首页 > news >正文

成都创新互联做的网站怎么样郑州网络工程学院

成都创新互联做的网站怎么样,郑州网络工程学院,手机网站开发解决方案,昆明网站排名优化公司哪家好前言 C语言文件接口 C 语言读写文件 1.C语言写入文件 2.C语言读取文件 stdin/stdout/stderr 系统文件IO 文件描述符fd#xff1a; 文件描述符分配规则#xff1a; 文件描述符fd#xff1a; 前言 我们早在C语言中学习关于如何用代码来管理文件#xff0c;比如文件的…前言 C语言文件接口 C 语言读写文件 1.C语言写入文件 2.C语言读取文件 stdin/stdout/stderr 系统文件IO 文件描述符fd 文件描述符分配规则 文件描述符fd 前言 我们早在C语言中学习关于如何用代码来管理文件比如文件的输入和文件的输出一些文件的接口如何深入学习文件的知识在Linux下一切皆文件今天我们探讨Linux的基础I/O。 1文件内容属性 2访问文件之前都需要先打开文件并且对文件的修改都是通过执行代码的方式完成的文件必须加载到内存中 文件被访问被修改必须得在内存中完成因为CPU只能访问内存所以文件必须加载到内存中。 打开文件-文件被加载到内存中 3文件由谁打开 -  由进程打开文件 4 一个进程可以打开多个文件由操作系统管理多个被打开的文件那么这些文件是怎样被管理的  先描述再组织内核中一定要有描述被打开文件的结构体使用其定义对象 5系统中不是所有的文件都被进程打开了 没有被打开的文件就在磁盘中 C语言文件接口 C 语言读写文件 文件操作     首先要打开文件打开成功返回文件指针打开失败返回NULL     最后要关闭文件 代码操作 FILE *fopen(const char *path, const char *mode);     int fclose(FILE *fp); fwritesize_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream )fcloseint fclose ( FILE * stream ); 1.C语言写入文件 int fputs(const char *s, FILE *stream); int fprintf(FILE *stream, const char *format, ...); 1. 如下我们以w的方式打开文件以w方式打开文件会先清空文件的内容然后再向文件写入内容。 #include stdio.hint main() {FILE *fpfopen(./log.txt,w);if(fpNULL){perror(fopen);return 1;}fclose(fp); return 0; } 2. 我们使用a方式append 打开文件  a方式 是向文件的末尾追加内容 #include stdio.h #include unistd.h #include string.hint main() {FILE *fp fopen(log.txt,a);if(fp NULL){perror(fopen);return 1;}const char* s hello linux\n;fwrite(s,strlen(s),1,fp);return 0; }2.C语言读取文件 char *fgets(char *s, int size, FILE *stream); int fscanf(FILE *stream, const char *format, ...); #include stdio.h #include unistd.h #include string.h int main() {FILE *fp fopen(./log.txt,r);if(fp NULL){perror(fopen);return 1;}char buffer[64];while(fgets(buffer,sizeof(buffer),fp)){printf(%s,buffer);}return 0; } stdin/stdout/stderr C默认会打开三个输入输出流分别是 stdin       标准输入  键盘设备 stdout     标准输出  显示器设备 stderr      标准错误  显示器设备 仔细观察发现这三个流的类型都是FILE*, fopen返回值类型文件指针 stdin、stdout、stderr 都可以直接使用例如 系统文件IO 上面的 fopen fclose fread fwrite 都是C标准库当中的函数我们称之为库函数libc。而 open close read write lseek 都属于系统提供的接口称之为系统调用接口 访问文件不仅仅要有C语言上的文件接口OS必须提供对应的访问文件的系统调用 man open查看 #include sys/types.h #include sys/stat.h #include fcntl.hint open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); 参数 pathname: 要打开或创建的目标文件 flags: 打开文件时可以传入多个参数选项用下面的一个或者多个常量进行“或”运算构成flags。参数: O_RDONLY: 只读打开O_WRONLY: 只写打开O_RDWR : 读写打开 这三个常量必须指定一个且只能指定一个 O_CREAT : 若文件不存在则创建它。需要使用mode选项来指明新文件的访问权限O_APPEND: 追加写 返回值 返回值 成功新打开的文件描述符 失败-1 来看下面的例子 #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h #include unistd.hint main() {int fd open(./log.txt,O_WRONLY | O_CREAT);if(fd 0){printf(open error\n);// return 1;}close(fd);return 0; } 此时我们可以观察到 创建出来的文件的权限是乱的 这是因为没有这个文件要创建它系统层面就必须指定权限是多少我们采用权限设置的八进制方案 #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h #include unistd.hint main() {int fd open(./log.txt,O_WRONLY | O_CREAT,0644);if(fd 0){printf(open error\n);return 1;}close(fd);return 0; } 此时的权限就正常了。 其中我们发现,我们传入的flag为 O_WRONLY|O_CREAT,中间为什么要用|连接起来呢 这是一种用户层给内核传递标志位的常用做法。int有32个bit位一个bit代表一个标志就可以传递多个标志位且位运算效率较高。这些O_RDONLY、O_WRONLY、O_RDWR 都是只有一个比特位是1的数据并且相互不重复这样 |在一起就能传递多个标志位。 看看下面这个例子 #include stdio.h #include unistd.h #include string.h#define ONE 1 #define TWO (11) #define THREE (12) #define FOUR (13) #define FIVE (14)void Print(int flag) {if(flag ONE ) printf(1\n);if(flag TWO) printf(2\n);if(flag THREE) printf(3\n);if(flag FOUR) printf(4\n);if(flag FIVE) printf(5\n); }int main() {Print(ONE);printf(------------\n);Print(TWO);printf(------------\n);Print(ONE|TWO);printf(------------\n);Print(THREE|FOUR|FIVE);printf(------------\n);Print(ONE|TWO|THREE|FOUR|FIVE);printf(------------\n);return 0; }文件描述符fd open函数的返回值是就是文件描述符类型为int下面我们来看看fd的值 #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h #include unistd.h #include string.hint main() {int fd1 open(./log1.txt,O_WRONLY | O_CREAT, 0644);int fd2 open(./log2.txt,O_WRONLY | O_CREAT, 0644);int fd3 open(./log3.txt,O_WRONLY | O_CREAT, 0644);int fd4 open(./log4.txt,O_WRONLY | O_CREAT, 0644);printf(fd:%d\n,fd1);printf(fd:%d\n,fd2);printf(fd:%d\n,fd3);printf(fd:%d\n,fd4);close(fd1);close(fd2);close(fd3);close(fd4);return 0; } 我们可以看到fd的值是从3开始的一次打印出了3、4、5、6 那么前面的012去了哪里 这时候我们想到了stdinstdoutstrerr 当我们的程序运行起来变成进程默认情况下OS会帮助我们打开三个标准输入输出012其实分别对应的就是标准输入stdin、标准输出stdout、标准错误stderr。对应硬件设备也是键盘、显示器、显示器。 0代表标准输入 1代表标准输出 2代表标准错误 #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h int main() { int fd open(myfile, O_RDONLY); if(fd 0){ perror(open); return 1; } printf(fd: %d\n, fd); close(fd); return 0 } 此时输出结果为 fd3 再关闭0或者2 #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h int main() { close(0); //close(2); int fd open(myfile, O_RDONLY); if(fd 0){ perror(open); return 1; } printf(fd: %d\n, fd); close(fd); return 0; }得到的结果会是fd0 或者fd2 文件描述符分配规则 这样文件描述符被分配为01234678… 这样从0开始连续的整数。 并且会优先分配 最小的未被使用过的。每次给新文件分配的fd是从fd_array[]中找一个最小的、未被使用的作为新的fd。 所有的文件操作都是进程执行对应的函数即本质上是进程对文件的操作。 如果一个文件没有被打开这个文件是在磁盘上。如果我创建一个空文件该文件也是要占用磁盘空间的因为文件的属性早就存在了(包括名称、时间、类型、大小、权限、用户名所属组等等)属性也是数据所谓“空文件”是指文件内容为空。 即磁盘文件 文件内容 文件属性。事实上我们之前所学的所有文件操作都可以分为两类对文件内容的操作 对文件属性的操作(fseek、ftell、rewind、chmod、chgrp等等). 要操作文件必须打开文件(C语言fopen、C打开流、系统上open)本质上就是文件相关的属性信息从磁盘加载到内存。 操作系统中存在大量进程进程可以打开多个文件即进程 : 文件 1 : n 系统中可能存在着更多的打开的文件(暂时不考虑一个文件被多个进程打开的特殊情况)。那么OS要不要把打开的文件在内存中(系统中)管理起来呢那么就要上管理的六字真言先描述再组织 打开的这么多文件怎么知道哪些是我们进程的呢操作系统为了让进程和文件之间产生关联进程在内核创建struct files_struct 的结构这个结构包含了一个数组 struct file* fd_array[] 也就是一个指针数组把表述文件的结构体地址填入到特定下标中。 文件描述符fd 此时我们cat命令查看log.txt文件内容为空 #includestdio.h #includeunistd.h #includesys/types.h #includesys/stat.h #includefcntl.h #includestring.h int main() {close(1);int fdopen(log.txt,O_WRONLY|O_CREAT|O_TRUNC,0666);printf(fd:%d\n,fd);return 0; }我们这段代码旨在打开log.txt文件并且向显示器上打印fd的值。 但是我们执行程序之后显示器上并没有出现我们期望的fd的值 反而我们cat 一下log.txt发现fd的值竟然打印在了log.txt文件中 首先分析一下fd的值 我们关闭了1 此时1 就是最小的且未被使用的所以此时open的返回值是1 对于本应打印在显示器上的值打印在文件中这件事情printf底层封装了一些writestdout等 此时传给printf的fd为1那么将 文件描述符1 传递给进程后进程就开始向log.txt文件中打印信息 同时我们也知道了 printf底层是在向标准输出(stdout)打印 int fprintf(FILE *stream, const char *format, ...); stdout - FIEL{fileno 1} - log.txt// stdout只认识1只对1输入输出 extern    dup2 #include unistd.h int dup2(int oldfd, int newfd); //oldfd-newfd dup2() makes newfd be the copy of oldfd, closing newfd first if necessary, but note the following: *  If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed. *  If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd. 拷贝的是fd对应内容最终相当于全部变成old.
http://www.dnsts.com.cn/news/91921.html

相关文章:

  • 北京游戏网站建设现在做一个网站系统多少钱
  • 网站php环境搭建合肥建站公司seo
  • 常州网站制作公司响应式网站开发支持ie6解决
  • 上海html5网站制作公司长沙旅游必去的八个景点
  • 长沙做网站建设的做网页素材
  • 成都网站建设公司排名网站上的彩票走势图是怎么做的
  • 济南制作网站公司吗网络规划设计师下午题2023估分
  • 什么网站能看到专业的做面包视频广州网站建设方案
  • 郓城网站建设费用广州网络推广引流
  • 商务网站如何推广哪个网站做不锈钢好
  • 清华大学学生工作做网站如何注册一个企业邮箱
  • 个人网站怎么建外贸网站推广如何做
  • 樱桃企业网站管理系统v1.1-cms优秀企业简介100字
  • 网站域名备案主机名网络服务器配置与管理考试题
  • 秦皇岛海港区建设局网站湖北网站建设网址
  • 网站备案审核流程图专业ppt代做
  • wordpress网站更改主题信息凡科商城官网旗舰店
  • 郑州影楼网站建设WordPress博客系统安装
  • 响应式网站建设品牌全网天下公司注册要求
  • 什么人最需要建设网站vs2015 做网站
  • 网页制作怎么上传到网站奇璐荣获北京十大高端设计公司称号
  • 长乐区建设局网站模版网站有源代码吗
  • 做彩投网站犯法吗火车头wordpress 缩略图
  • 网站建设技术方面论文房屋装修设计师怎么收费
  • 宁波网站建设公司哪有做聊天室cpa用什么类型的网站好
  • 论述网站建设的步骤卡片式网页布局
  • 衡阳市网站建设公司果酱wordpress
  • 旅游网站分析拼多多网站建设合同
  • 上海虹口网站建设公司做网站自己申请域名还是对方
  • 黄村做网站哪家快邢台做网站推广的公司是哪家?