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

千岛湖建设集团网站做全世界的生意的网站

千岛湖建设集团网站,做全世界的生意的网站,运城做网站电话,海南网红打卡旅游景点文章目录 一、共识原理二、C系列文件接口三、从C过渡到系统#xff1a;文件系统调用四、访问文件的本质 一、共识原理 文件 内容 属性 文件分为打开的文件 和 没打开的文件 打开的文件#xff1a;是谁打开的#xff1f;是进程#xff01;----所以研究打开的文件本质是研… 文章目录 一、共识原理二、C系列文件接口三、从C过渡到系统文件系统调用四、访问文件的本质 一、共识原理 文件 内容 属性 文件分为打开的文件 和 没打开的文件 打开的文件是谁打开的是进程----所以研究打开的文件本质是研究进程和文件的关系 没打开的文件在哪里放着呢在磁盘上放着。我们最关注什么问题没有被打开的文件非常多。文件如何被分门别类的放置好—即我们要快速的进行增删查改—即快速的找到文件 所以上面的问题总结下来就是如何存储 一个文件被打开必须先被加载到内存中 进程 打开的文件 1n(即一个进程可以打开任意个文件) 由以上两点我们可以得到操作系统内部一定存在大量的被打开的文件 ----OS要不要管理这些被打开的文件呢 —肯定是要的那么怎么管理呢----先描述在组织 ---- 所以在内核中一个被打开的文件都必须有自己的文件打开对象包含文件的很多属性。struct XXX {文件属性 struct XXX* next}; 二、C系列文件接口 如下所示在下面这个函数中 第一个参数是路径第二个参数是打开方式。返回值是FILE*即文件指针 如下所示当我们使用如下代码的时候 #include stdio.hint main() {FILE* fp fopen(log.txt,w);if(fp NULL){perror(fopen);return 1;}fclose(fp);return 0; }因为我们是以写的方式打开文件所以如果不存在这个文件他会自动创建一个这样的文件 注意这里的打开文件的路径和文件名默认在当前路径下新建一个文件。 那么这里当前路径是什么呢其实是进程的当前路径cwd 比如下面的代码中 #include stdio.h #include unistd.hint main() {printf(PID:%d\n,getpid());FILE* fp fopen(log.txt,w);if(fp NULL){perror(fopen);return 1;}fclose(fp);sleep(1000);return 0; }我们可以去查看一下它的当前目录 在这里如果我们更改了当前进程的cwd就可以把文件新建到其他目录了 而我们在一个进程中更改当前目录可以使用chdir 所以我们可以使用如下代码 #include stdio.h #include unistd.hint main() {chdir(/home/jby_1);printf(PID:%d\n,getpid());FILE* fp fopen(log.txt,w);if(fp NULL){perror(fopen);return 1;}fclose(fp);sleep(1000);return 0; }我们可以观察一下运行结果。可以发现这个文件去对应的路径创建了。 我们再看一下当前的目录 以上是文件的打开我们现在重点来看一下文件写入的操作 如下是文件写入的函数 它的作用是将nmemb个size大小的ptr处的数据写入到一个文件中 如下代码所示 #include stdio.h #include unistd.h #include string.h int main() {printf(PID:%d\n,getpid());FILE* fp fopen(log.txt,w);if(fp NULL){perror(fopen);return 1;}const char* message hello linux message;fwrite(message,strlen(message),1,fp);fclose(fp);return 0; }运行结果如下所示 但是如果我们将上面代码的message修改了之后 我们在运行一下里面的内容也随之改变了 这里我们会发现原来文件的内容全部不见了。所以说w方法写入之前都会对文件进行清空处理 这就类似于之前的重定向就是相当于用w的方法打开了文件。然后写入内容 所以如果我们使用重定向的时候前面什么也没有就相当于清空了这个文件。当我们用w的方法打开一个文件以后里面什么也都不会有了。 那么现在我们再来看一下上面这个代码 我们前面在这里没有1不过c语言中默认会添加上\0那么这里需要加1吗 我们先运行一下然后我们就会发现这个文件里面的内容就变成了这样了出现了一个乱码 所以说这里是不需要1的因为字符串后加上\0是C语言的规定与文件有什么关系呢 不过在打开文件的方式中有一个方式是a方式它是在文件的结尾写。如果文件不存在则创建一个文件 我们试一下下面这个代码 运行结果为 所以说像我们之前的追加重定向其实就是a方式的打开文件 所以w/a都是写入w清空并从头写a在文件结尾追加写 我们知道Linux下一切皆文件。在C语言中默认会打开三个流stdin,stdout,stderr。如下图所示这三个流的类型就是文件指针。 其实类似的C中也会默认打开三个流cin cout cerr 如果我们想向显示器打印也是可以的 我们先看下面的代码。使用fprintf我们也可以实现前面的在文件中打印的操作 对于fprintf我们也可以将它的第一个流改为stdout 这样的话运行结果为就成功的向显示器打印了 如果我们想在stderr流中去写的话 但从运行结果来看似乎好像没有什么太大的区别 其实 三、从C过渡到系统文件系统调用 我们知道文件其实是在磁盘上的磁盘是外部设备。所以访问文件其实是访问硬件 我们知道计算机中是分层的 用户 程序 - std lib / c / c 系统调用 操作系统 硬件驱动 硬件 我们知道我们是不可直接访问硬件的必须要自顶向下贯穿访问。而操作系统不相信任何人所以就需要提供系统调用 所以几乎所有的库只要是访问硬件设备必定要封装系统调用。即printf/fprintf/fscanf/fwrite/fread/fgets/gets/…这些都是库函数他们必定要封装系统调用接口 如下所示这些就是文件系统调用接口 我们先只考虑这两个open函数。 这两个open系统调用接口一个有两个参数一个有三个参数 上面的这个是下面的子集 所以我们先只谈三个参数的open int open(const char *pathname, int flags, mode_t mode);在这里第一个参数是对应文件的路径可是是绝对/相对都可以。也可以直接是文件名那么默认当前目录 而第二个参数中我们可以看到如下所示 即flag就是一个打开的模式。必须包含O_RDONLYO_WRONLY或者O_RDWR。 这些其实就是比特位的传参方式。 对于它的返回值如果失败返回-1 我们先看如下代码 运行结果为打开失败了 这是因为我们刚刚用到的这个O_WRONLY选项它并不会新建文件。我们得告诉操作系统如果文件不存在我们需要新建它。所以我们还得加上O_CREAT选项 运行结果为 但是我们发现这里新创建的文件的权限是完全不对的 这是因为在linux中要创建一个文件必须得告诉权限是什么。所以就需要第三个参数了。设置好权限 此时新建的文件的权限已经不是刚刚那种乱码的样子了 不过这里我们发现创建的文件它的权限也不是666而是664这是因为我们之前所说的linux创建一个文件有默认的umask。这是由于这个umask是0002所以最后一个才出现了一些问题 但是如果我们非要创建一个666的文件。我们就需要用这个umask系统调用了 它可以将代码里面的umask给修改掉。这里只影响该进程不影响系统的 由于就近原则 open就会听进程的umask。 运行结果为。可以看到权限确实被改为了666 对于这个open函数它的返回值为一个int这个整数我们称为file descriptor,即文件描述符如果打开失败则为-1。 如果我们想要关闭一个文件可以用close 它的参数正好就是文件描述符所以我们可以传入一个文件描述符就可以关闭对应的文件了 还有一个系统调用是write 它的功能是向fd文件中写入buf的count字节 运行结果为 如果我们紧接着将字符串改短一些 那么最终的结果为 现象就是原来的内容都保留着但是会从文件开始覆盖式的写入但是并不会清空。 那么如果我们也想做到清空操作呢 在我们打开文件的时候即open函数中的第二个参数我们可以使用O_TRUNC,即清空 此时我们就可以看到原来的就被清空了 那么如果我们想要实现追加写的功能呢我们可以使用O_APPEND 运行结果为 这样就实现了追加的功能 所以我们得到的结论是 FILE* fp fopen(log.txt, a); //上面的代码下层一定封装了下面的系统调用接口 int fd open(log.txt, O_WRONLY|O_CREAT|O_APPEND, 0666);FILE* fp fopen(log.txt, w); //上面的代码下层一定封装了下面的系统调用接口 int fd open(log.txt, O_WRONLY|O_CREAT|O_TRUNC, 0666);所以说无论是什么语言最终底层一定会采用同样的接口。底层都是open只是他们的上层有所区别罢了。 不过我们会好奇的是上层的函数返回值是指针而下层的系统调用接口的返回值是int它们是如何联系起来的呢 四、访问文件的本质 如下图所示我们知道文件都是在磁盘中存储着的并且文件需要由一个进程来打开那么进程要打开这个文件。就需要为这个文件创建对应的内核数据结构即struct file。这个结构体里面存储着一个被打开文件的各种信息。当打开了多个文件的时候这些结构体就会用一个双向链表连接起来。 也就是先描述在组织此时对文件的管理就变为了对这个链表的增删查改 可是我们的系统存在多个进程。那么哪一个文件是哪一个进程的呢所以我们需要建立对应关系 如下图所示我们的进程PCB结构体里面就有一个指针它指向struct files_struct这样的一个结构体这个结构体里面有一个struct file* fd_array[]数组数组里面存储着很多struct file*指针然后每当这个进程打开一个文件时要创建一个struct file结构体然后将这个结构体的地址放入一个没有被使用的下标中。 而这个表就是文件描述符表。而前面的open系统调用中这个返回值,就是对应文件描述符表中的下标。 所以这个fd本质就是一个数组的下标。我们使用write这些接口的时候就需要使用文件描述符来进行辨认文件 所以最终文件管理和进程管理就通过这个下标产生了关联 我们也许会思考既然都已经让进程管理起来了文件为什么要让文件用双链表呢因为进程也可能会崩掉。 现在我们已经了解了访问文件的本质了open的返回值其实就是文件描述符表的下标那么既然如此。我们来验证一下 运行结果为 我们可以在多验证一些 运行结果为 这里返回连续的下标我们也能理解我们也知道失败会返回-1。那么012这些下标在哪呢 我们会注意到012刚好是3个。在C语言中刚好要打开三个流 C语言认为要打开三个linux下一切皆文件。 所以每一个被打开的文件它在底层根本就不存在这个FILE*流在操作系统中只认fd。 所以我们现在可以验证一下这三个流就是012这三个文件 运行结果为 所以这两个分别为stdout,stderr 我们现在在验证一下stdin 对于这个我们可以用read系统调用接口 运行结果为 注意在这里由于操作系统并不知道我们读取的是字符串它最后也不会加上\0所以我们需要自己加上 这样一来也就验证了0是stdin 所以当一个C语言程序启动的时候会打开三个标准输入输出流这个是C语言的特性吗 答案显然不是是操作系统的特性进程默认会打开键盘显示器显示器 那么为什么操作系统要这么做 因为我们电脑刚打开显示器键盘早就被操作系统打开了。我们在编程的时候必须得用显示器和键盘输入和查看结果所以语言默认都能打开。 那么在C语言中这个FILE是什么呢 这个FILE是C库自己封装的一个结构体这个结构体里面必须包含文件描述符。因为操作系统只认文件描述符。 我们可以来证明一下 运行结果为 所以现在我们就知道了这里有两种的封装了。 一种是库函数封装了系统调用接口一种是FILE封装了文件描述符 如果我们直接将1号文件给关了 我们会发现什么也没有了 因为一号就是显示器文件。而printf里面必然调用了这个1号文件描述符。 如果我们将代码改为下面的 那么结果为 因为我们用的是2号文件去写的。我们关的只是一号文件 还有一点是在struct file结构体里面其实还有一个信息是引用计数count。因为可能多个文件描述符指向同一个文件。一个文件描述符指向就是1两个指向就是2. 所以我们关闭文件去调用close的时候它的工作其实很简单只需要引用计数减减然后将这个指针位置置空。然后判断这个引用计数是否为0如果不为空则什么也不用做到如果为空那么就在去回收这个struct file对象。 所以这就是我们刚刚关闭了1号文件2号文件还能继续打印的原因。因为仅仅只是引用计数减减了。 而C中的那些fstream中也是一样的包含fd的。
http://www.zqtcl.cn/news/362146/

相关文章:

  • 静安手机网站建设常见的网络营销方法及其效果
  • 怎么改版网站湖南长沙地图
  • 中卫网站推广公司如何自创app软件
  • 无棣网站建设电子商务网站设计原理书籍
  • 做t-shirt素材网站企业网站建设结论
  • 唐山公司做网站查询建筑资质的网站
  • 邯郸的网站建设网站正能量入口
  • 网站导航栏最多可以做几个宝安网站设计排名
  • 自己怎样用手机建网站网件app
  • 周口网站开发西安市建设厅网站
  • 怎么授权小说做游戏网站论坛网站开发语言
  • 烟台商城网站建设怎么样引流顾客到店方法
  • 北京做网站公司的排名python基础教程pdf
  • 网站建设为什么学flash建设工程询价网站有哪些
  • 网站内容建设机制企业管理模式有哪些
  • 中山网站建设文化价格建网站域名注册
  • 手机电影网站怎么做大连最新发布
  • 珠三角网站建设网页制作专业知识
  • 罗湖微信网站制作深圳做网站哪个公司最好
  • ps如何做ppt模板下载网站网站模板分类
  • 网站建设在线网站服务器和直播服务器一样吗
  • iapp网站做软件教程朋友圈广告投放平台
  • 优门设 网站网站代理 正规备案
  • 衡水做wap网站上海做网站吧
  • seo推广思路seo线下培训班
  • 没有备案的网站怎么做淘宝客html5开发手机网站
  • 酒店旅游团购网站建设推广普通话实践总结
  • 基本的网站开发技术路线建设网站的好处有哪些
  • 网站排行怎么做wordpress all in one seo插件
  • 河北特定网站建设推荐wordpress添加vip用户组