初识Linux · 文件(1)

打印 上一主题 下一主题

主题 823|帖子 823|积分 2469

目次
前言:
回顾语言层面的文件
理解文件的准备知识
文件和磁盘
利用和熟悉体系调用函数

前言:

本文以及下篇文章,揭破的都是Linux中文件的奥秘,对于文件来说,初学Linux第一节课打仗的就是文件,对于C语言,我们利用fopen可以打开文件,对于C++,我们可以利用ofstream可以打开文件,那么对于这么多打开文件的方式,岂非每个差别的语言,我们都要单独去学习如何利用对应的函数吗?
当然不是,我们不妨追念最初学习的OS的结构图:

对于该结构,我们设想一个题目,文件属于那里?
文件属于磁盘,而磁盘属于硬件,那么对于文件来说,我们能跨过OS直接操控文件吗?当然不可以,那么C语言提供的文件函数是否……?留个牵挂。
如今就开始揭秘文件的神秘面纱吧!

回顾语言层面的文件

我们在C语言打仗到的文件函数不知道同学们是否忘记了,假如忘记了,我们简朴的回忆一下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5.     FILE* fp = fopen("log.txt","w");
  6.     if(fp == NULL)
  7.     {
  8.         perror("fp");
  9.         exit(1);
  10.     }
  11.     fclose(fp);
  12.     return 0;
  13. }
复制代码
通过fopen打开文件,以w的形式对文件进行写入,对于文件操纵熟悉的同学应该知道,w这个方式进行写入的话,默认是在当前目次进行写,并且,重复运行该步伐,会覆盖原来的log.txt。
这是基本知识。
那么提问了:为什么体系知道要在当前目次创建文件大概是写文件呢?
这里不妨多说几句,假如我们想要在语言层面,深刻理解文件的话,是不太实际的,由于高级语言的函数肯定是和体系调用存在肯定关联的,所以我们必要先回顾一下高级语言的文件操纵。
那么回到最开始的题目,为什么体系知道要在当前目次创建文件呢?
我们追念,是谁运行的我们的代码?是谁打开的文件?我们?照旧步伐?假如是步伐,步伐的本质是什么?
步伐的本质是历程
所以,本质上是历程打开的我们的文件,这是第一个我们必要留意的点。
那么在Linux中,我们另有一个创建文件的方式,除了利用函数,我们可以该指令:

创建文件,这是重定向符,这是我们所熟知的,那么为什么它可以重定向呢?

以及我们第一次创建之后,写入了文件,我们再次重定向一下,文件的内容就没有了,这是为什么呢?
以及,文件是不是由OS进行统一管理呢?
假如是由OS进行统一管理,那么假如管理的呢?这里答案是比力明显的,先描述再组织
对于这里的内容,我们都必要后面的知识作为补充来了解,所以,如今进入到准备知识部分。

理解文件的准备知识

文件和磁盘

在第一个大标题来说,我们已经知道我们利用高级语言的函数来调用OS后面的文件,那么高级语言的函数是假如调用文件的呢?
不出意外,它们是通过调用体系层面的函数来利用文件的。所以本质来说,高级语言的文件操纵函数都是通过封装体系调用的函数来实现文件操纵的。
那么,我们可否直接通过体系调用,来实现文件操纵呢?
利用和熟悉体系调用函数

先来简朴的看上一段代码:
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. int main()
  8. {
  9.     int fd = open("test.txt",O_WRONLY | O_CREAT);
  10.     if(fd < 0)
  11.     {
  12.         perror("open");
  13.         exit(-1);
  14.     }
  15.     return 0;
  16. }
复制代码
这是体系层面的open函数,利用了两个宏O_WRONLY| O_CREAT,open函数的返回值是int等,查看文档看详细内容:

利用2号手册可以查看,2号手册也是代表的open是一个体系调用函数,并且一大堆的头文件,照旧有点麻烦的,其次,open函数可以有三个函数参数,但是对于我们刚才的代码,为什么我们传的是类似于宏的|操纵呢?
不卖关子,O_CREAT就是宏,其他也是,我们可以在2号手册里面查看许多宏。
对于O_WRONLY等,为什么我们要传两个宏的或操纵呢?
这里提问:
  1. void func(int a1,int a2,int a3,int a4...)
复制代码
对于一个函数来说,假如参数的数目是可变的,我们不可能就一直这么写参数吧?
除了C++的可变模板参数可以解决,Linux中我们怎么解决呢?或着说,源码里面是怎么解决的?
我们看一段代码就知道了:
  1. void Func(int a)
  2. {
  3.     if(a&&ONE)
  4.     printf("ONE\n");
  5.     if(a&&TWO)
  6.     printf("TWO\n");
  7.     if(a&&THREE)
  8.     printf("THREE\n");
  9. }
  10. int main()
  11. {
  12.     Func(ONE);
  13.     Func(ONE | THREE);
  14.     Func(ONE | TWO);
  15.     return 0;
  16. }
复制代码

那么,我们可以将printf换成其他功能,这就是源码里面的操纵,其中的参数flags,就叫做标记位。
第三个参数就好说了,就是权限而已,但是呢,我们先不带权限创建了文件之后,看看权限是什么呢?

ll之后,test甚至都标红了,前面的权限呢?就变成乱码了。这是由于我们没有设置。
所以相对来说呢,两个参数的open更多是用于已经创建好的文件进行操纵的。
  1. int main()
  2. {
  3.     int fd = open("test.txt",O_WRONLY | O_CREAT,0666);
  4.     if(fd < 0)
  5.     {
  6.         perror("open");
  7.         exit(-1);
  8.     }
  9.     return 0;
  10. }
复制代码

我们必要将原来的文件删除了之后,然后再设置即可.
但是有一个奇怪的征象,为什么test.txt的权限是664而不是666呢?相信对前文文件有所了解的话,就知道权限掩码,而体系中,存在一个函数,可以动态的修改掩码:
  1. int main()
  2. {
  3.     umask(0);
  4.     int fd = open("test.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
  5.     if(fd < 0)
  6.     {
  7.         perror("open");
  8.         exit(-1);
  9.     }
  10.     return 0;
  11. }
复制代码
此时权限就正常了,但是呢,体系中的掩码:

一看照旧0002,岂非不影响我们动态修改吗?
请记住,就近原则
如今引入3个题目:
1. fopen的w模式,是将文件创建,假如存在,就清空。那么我们先来看看这个宏:

  1. int main()
  2. {
  3.     umask(0);
  4.     int fd = open("test.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
  5.     if(fd < 0)
  6.     {
  7.         perror("open");
  8.         exit(-1);
  9.     }
  10.     return 0;
  11. }
复制代码
truncate的意思就是截断,利用起来和w是一样的:

此时文件清空。
那么:
宏O_TRUNC和w模式之间的关系是什么?
2.fd的返回值有345,但是没有012,0对应的是尺度输入,键盘,1和2对应的硬件都是显示器,但是1是尺度输入,2是尺度错误。C语言中默认打开三个流。
返回值和C语言默认打开的流的接洽究竟是什么呢?
3.宏另有O_APPEND,C语言中的函数fopen的a模式代表追加,APPEND的意思也是追加。
差别的宏与差别的模式之间的接洽是什么呢?
预知后事如何~请看下篇~

感谢阅读!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

怀念夏天

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表