Linux - 文件操作和系统接口

这篇具有很好参考价值的文章主要介绍了Linux - 文件操作和系统接口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

                                                              Linux - 文件操作和系统接口

                                               感谢各位 点赞 收藏 评论 三连支持

                                              本文章收录于专栏【Linux系统编程】   

                                                     ❀希望能对大家有所帮助❀

                                                       本文章由 风君子吖 原创

        ​​​​​​​        ​​​​​​​        ​​​​​​​               Linux - 文件操作和系统接口

前言

 对于文件操作,不知大家是否有过接触,例如(fopen,fclose...等),那么大家在刚接触使用这些文件接口的时候,是否有过一些难以言喻的懵懂感,不仅不太理解,而且难以刻于脑海。

本章内容不仅会讲解文件操作内容知识,还会讲授一个重要的概念,这个概念会影响你对于Linux系统编程的学习!

文件

什么是文件? 

对于我们日常使用来言,文件似乎就是我们每天运行的游戏,app(.exe)或者我们写的c语言代码(.c和.cpp等),它们都是在磁盘上存储的。  而这种观点知识狭义的,实际上,对于文件有着更广的范域。

文件不仅仅只是它存储的数据,还有它的属性(例如它的权限,它的拥有者、所有组,它的创建时间,它的类型)。

万物皆文件

对于操作系统而言 ,只要是能够被input读取或者output输出的设备就叫做文件!

而我们的键盘和显示器也有着具备读写的能力,这说明它们也可以被称之为文件,而我们日常使用的狭义上的文件是被存储在磁盘上的,我们如果要进行读写,也是对磁盘进行读写,那么也就说明磁盘也是文件。

而对于硬件的读写操作,只有操作系统才有权限进行读写!

文件的操作

对文件的操作,无非就是对文件的数据和文件的属性操作。

那么对于文件,我们知道了它具备读写的作用,那么这种读写的属性,是针对谁而言呢?

磁盘上的文件: 具备read(读)、write(写)的属性。

显示器:printf、cout  ->这是write(写)的属性。

键盘: scanf、cin -> 这是read(读)的属性

是不是对于键盘和显示器的属性有些诧异?,我们在显示器上难道不是读吗,不然怎么看到这篇文章?键盘不是我们一个一个打字才输进去的吗,可为什么却是读?

举一个例子,一个文件在磁盘上存储着,我们如果要访问一个文件,就需要写代码运行起来后才访问这个文件,而本质其实是进程在访问文件!

所以,我们不能站在自己的角度去理解它们的属性,我们应该站在进程的角度去理解,而进程是被加载到内存的。  对于一个进程,我们需要从键盘上读取到数据,而进程可以向显示器输出信息让我们看到。

回顾C语言的文件操作函数

打开一个文件,C语言提供的接口

Linux - 文件操作和系统接口

写文件

 #include<stdio.h>
 #include<unistd.h>
 #include<string.h>
 int main()
 {
   FILE* fl = fopen("file.txt","w");                                                                                                                                           
   if(fl == NULL)
   {
     perror("Open");
     return 1;
   }
   //文件write
   const char* str1 = "hello fputs\n";
   fputs(str1,fl);
   const char* str2 = "hello fwrite\n";
   fwrite(str2,strlen(str2),1,fl);
   const char* str3 = "hello fprintf\n";
   fprintf(fl,"%s",str3);
   fclose(fl);
   return 0;
 }

Linux - 文件操作和系统接口

fopen以w的形式打开,如果该名字文件不存在则会在当前目录下创建一个该名字的文件。

而这个文件是根据什么在哪里创建的呢? 当前目录?谁的当前目录?

答案是进程当前的工作目录!

Linux - 文件操作和系统接口

 读文件

Linux - 文件操作和系统接口Linux - 文件操作和系统接口

效果是不是跟cat指令一样?

那么我们这就来模拟一下cat

cat指令的模拟

Linux - 文件操作和系统接口

Linux - 文件操作和系统接口

系统接口

刚刚我们以上回顾的文件操作的接口函数都是C语言给我们提供的接口,但是通过我们之前已学的知识,如果要对硬件进行读写操作,只有操作系统有这个权限,用户是没有权限的。而我们使用的fopen之类的函数都是语言层面上的接口,所以我们就可以知道语言提供给我们的函数,在它实现的底层必然调用了系统接口。

所以这里就引出了一个我们为什么要学习Linux系统编程的概念,在我们之前学习进程的等待,替换中,我们也接触过了系统提供的接口,我们可以清晰的感受到,对于语言层面上提供的接口,我们虽然说在使用上会简洁,方便许多,但是对于它的实际理解却略有不足,单看我们现在使用的C语言提供文件操作函数,我们虽然知道如何去用,但是难以理解它到底做了什么。

所以,学习Linux系统编程,是为了更好的去理解底层原理,强化我们的知识,我们的视野,为什么? 因为不同的语言,它们对于各自的功能的实现方式是不同的,对于底层实现的系统接口的封装也是不同的,所以,学习了系统接口,是为了更好的理解语言层面的函数在做什么? 而且还有一个好处就是,再去学各种不同的语言提供给你的功能接口,都会显得更加得心应手。

语言的跨平台性

这里又在引出一个概念,语言的跨平台性,什么是跨平台?  比如说你在Linux上写了一个代码,不仅可以在Linux系统下运行,还可以在Windows下也能运行,这就是跨平台性。

那么Windows和Linux提供的系统接口会是一样的吗?  但是是不一样的。

那么语言是如何实现 不同平台提供了不同的系统接口 但却实现了语言的跨平台性的呢?

答案是 实现C语言库的那些高级程序员为了兼容不同的平台,必然每个平台都要实现一份语言层面的函数,再通过条件编译进行动态裁剪就能够实现在不同的平台使用对应的函数。

Linux系统提供的文件操作接口

open

man 2 open

Linux - 文件操作和系统接口

先来看看第一个open

int open(const char *pathname, int flags);

先看返回值 是一个int类型,它返回的是如果文件打开成功,则返回该文件的文件描述符fd(对于文件描述符我们放在下一篇文章讲),而如果打开失败,则返回-1。 

第一个参数是pathname就是路径,这个很好理解。

第二个参数是flags(标识),这个是什么呢? 这个就很有意思了,这个涉及到位标识符的知识

先来看看man对于这个参数是干嘛用的?

Linux - 文件操作和系统接口

 这些全是大写的单词可以理解为选项,而从命名风格来看就可以知道这些都是宏,对于这些选项,每个选项都代表不同的意义,有的是代表追加,有的是代表创建...(大家下来可以都看看)

那么如果有这么多选项,我们该用什么办法把它们都能传进去呢? 如果是一个功能代表一个参数的话,那么不仅对于函数来说会显得臃肿不好看,更是针对系统接口来讲是不可饶恕的,效率太低了。采用位标识符就很好的解决了这个问题。

位标识符(重点)

以一个int来作为参数的话,他有几个比特位?28个 

0000 0000 0000 0000

而如果每个比特位代表一个选项的话,是不是就可以通过一个int 类型来完成28个选项的判断?  是的 

这种方法效率高效且占用空间极低,堪称完美!

示例

Linux - 文件操作和系统接口 Linux - 文件操作和系统接口

 通过按位与来实现传入多个选项

现在我们来上手一下使用open

Linux - 文件操作和系统接口

我们想对log.txt文件进行只写操作,所以传了O_WRONLY 

 Linux - 文件操作和系统接口

 而我们当前目录下是没有log.txt文件的

Linux - 文件操作和系统接口

 运行程序后发现打印出了 没有找到该文件或者文件夹,这是为什么,按照我们使用C语言的fopen,如果没有这个文件难道不是应该会自动创建这个文件吗,为什么这里没有创建?

这就提到了我们刚才说讲的,在语言层面上给你提供的接口对系统接口进行了封装,是为了让我们能够更方便地使用。

所以如果我们想要 如果没有这个文件就自动创建这个文件的效果,那么系统接口函数给了我们O_CREAT这个宏选项。

Linux - 文件操作和系统接口

 这个时候我们再运行一下程序

Linux - 文件操作和系统接口

 虽然log.txt文件被创建出来了,但是它的文件权限有问题!

这个时候第二个open就有了作用了

int open(const char *pathname, int flags, mode_t mode);

它的第三个参数就是针对如果要创建文件,对该文件的权限进行设置

而对于文件的权限设置我们已经不陌生了。

这个时候我们输入0666(八进制) 代表 -rw-rw-rw

Linux - 文件操作和系统接口

Linux - 文件操作和系统接口

运行程序之后,新生成的文件的权限虽然比上次的正确多了,但是为什么是-rw-rw-r--?我们设置明明的是-rw-rw-rw- 

 这是因为有掩码的存在!

umask(用户创建文件掩码)

Linux - 文件操作和系统接口

 使用umask指令可以查看当前的umask值

这里我的umask值是0002(八进制)转化为二进制就是0 000 000 010

那么掩码是怎么让我设置的0666权限编程0664的呢?

0666: 0 110 110 110                ->                          0 110 110 110 

0002: 0 000 000 010               -> 按位取反           1 111 111 101

                                                   ->按位与运算     & -------------------

结果:                                                                      0 110 110 100

这就是掩码的作用

那么有没有办法重新设置掩码呢? 系统提供了一个接口

mode_t umask(mode_t mask);

                                                                   Linux - 文件操作和系统接口                  

 设置umask值为0

Linux - 文件操作和系统接口

 Linux - 文件操作和系统接口

 这个时候创建的新文件的权限正确了!

close

Linux - 文件操作和系统接口

 close没什么好说的,传入文件的文件描述符fd就可以关闭文件

write

Linux - 文件操作和系统接口

 fd是要写入的文件的文件描述符,buf是要输入的字符串,count是期望写入的buf的字节数

返回值是实际写入的buf的字节数

先来看一下下面的代码

Linux - 文件操作和系统接口

注意open的参数,想在打开的log.txt文件写入aa。

此时的log.txt已经有数据

Linux - 文件操作和系统接口

运行代码之后

 Linux - 文件操作和系统接口

 发现log.txt在写入aa之前并没有清空原先log.txt中的数据,这是因为我们在open少传了个选项

Linux - 文件操作和系统接口

 Linux - 文件操作和系统接口

 这时就实现了fopen("log.txt","w")的完整功能。

而如果要实现fopen("log.txt","a")的功能,则需要把O_TRUNC替换为O_APPEND

Linux - 文件操作和系统接口

多运行几次程序 

Linux - 文件操作和系统接口

 这就实现了fopen("log.txt","a")的完整功能!

read

Linux - 文件操作和系统接口

 参数和返回值域write差不多,只不过这里的buf是需要从文件中读取内容

Linux - 文件操作和系统接口

 Linux - 文件操作和系统接口

 读取成功!

初识文件描述符fd

 对于文件描述符的内容,我会再重新写一篇文章专门针对文件再写一章,里面会详细讲解文件描述符和文件的密切关系,现在我们就来简单认识一下

首先对于我们上面写的代码,我们总能看到我们输出的fd为3

Linux - 文件操作和系统接口 Linux - 文件操作和系统接口

 能从结果发现文件描述符的似乎是一串连续的数字

而如果是一串连续的数字,那么为什么又是从3开始的呢?

这是因为 在我们运行c语言程序的时候,会默认打开stdin(标准输入) ,stdout(标准输出),stderr(标准错误)三个流,而这三个流文件,它们分别对应我们的键盘,显示器,显示器。

而它们的文件描述符分别是stdin(0),stdout(1),stderr(2)。

如何证明?

Linux - 文件操作和系统接口

 既然1代表标准输出,那么这个程序是不是也能将hello world输出到屏幕上?

Linux - 文件操作和系统接口

 正确的!

FILE是什么

先说结论,它是一个结构体,里面存储着一个被打开的文件的几乎所有内容(包括属性)

如何证明?

Linux - 文件操作和系统接口

 _fileno代表的就是文件描述符fd

Linux - 文件操作和系统接口

 对于FILE我也会在下一篇文章详细讲解!文章来源地址https://www.toymoban.com/news/detail-482075.html

到了这里,关于Linux - 文件操作和系统接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux操作系统(六):文件系统组件

    参考资料:阿秀的笔记 Linux 「一切皆文件」 不仅 普通的文件和目录 ,就连 块设备、管道、socket 等,也都是统一交给文件系统管理的。 如何唯一标识文件? 索引节点 inode ,记录了文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位

    2024年04月11日
    浏览(37)
  • Linux操作系统——文件详解

    首先,当我们在磁盘创建一个空文件时,这个文件会不会占据磁盘空间呢? 答案是当然会占据磁盘空间了,因为文件是空的,仅仅指的是它的内容是空的,但是该文件要有对应的文件名,文件的大小,文件的创建时间,文件的权限等等,这些叫做文件的属性,是一个往往被人

    2024年01月16日
    浏览(44)
  • [Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)

            hello,大家好,这里是bang___bang_ ,今天和大家谈谈Linux中的基础IO,包含内容有对应的系统文件I/O接口,文件描述符,理解重定向。    目录 1️⃣初识文件 2️⃣ 系统文件I/O接口 🍙open 🍙write 🍙read 🍙close 3️⃣文件描述符 🍙012 🍙内核中文件描述符的探究 🍙分配

    2024年02月12日
    浏览(37)
  • Shell命令操作Linux文件系统

      Linux文件系统是计算机操作系统中的一个关键组成部分,它用于管理和组织计算机上的数据和信息。先到根目录,然后打印当前目录下文件:   有一些比较常用的文件夹介绍如下:    /bin ——包含常见Linux 用户命令,比如 ls、sort、date和l chmod。    /home ——包含分

    2024年02月09日
    浏览(40)
  • 【Linux操作系统】探秘Linux奥秘:文件系统的管理与使用

    🌈个人主页: Sarapines Programmer 🔥 系列专栏: 《操作系统实验室》 🔖诗赋清音:柳垂轻絮拂人衣,心随风舞梦飞。 山川湖海皆可涉,勇者征途逐星辉。 目录 🪐1 初识Linux OS 🪐2 文件系统的管理与使用 🌍1. 实验目的 🌍2. 实验准备 🌍3. 实验内容 🌍4. 实验心得 📝总结

    2024年02月03日
    浏览(55)
  • 【linux深入剖析】操作系统与用户之间的接口:自定义简易shell制作全过程

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 Linux的Shell是一种命令行解释器,它是用户与操作系统内核之间的接口。 通过Shell,用户可以输入命令并与

    2024年03月18日
    浏览(56)
  • EditPlus连接Linux系统远程操作文件

    EditPlus是一套功能强大的文本编辑器! 1.File -FTP-FTP Settings; 2.Add-Description-FTP server-Username-Password-Subdirectory-Advanced Options 注意:这里的Subdirectory设置的是以后上传文件的默认目录 3.Encryption-Port-Use UTF-8 file names-OK-OK 连接成功! 选择目录之后就可以对Linux系统的文件进行操作。 也

    2024年02月14日
    浏览(54)
  • Linux操作系统实验三 文件管理(一)

      1.实验目的与要求 了解Linux文件系统目录结构 掌握目录管理的相关操作 掌握文件管理的相关操作 2.实验平台 实验室安装的实验环境(Linux操作系统)和头歌(www.educoder.net)实验平台(课程实验) 3.实验内容 文件系统目录结构理论知识练习 linux 下目录的创建、应用、查看、

    2024年02月03日
    浏览(54)
  • 【Linux操作系统】举例解释Linux系统编程中文件io常用的函数

    在Linux系统编程中,文件IO操作是非常常见和重要的操作之一。通过文件IO操作,我们可以打开、读取、写入和关闭文件,对文件进行定位、复制、删除和重命名等操作。本篇博客将介绍一些常用的文件IO操作函数。 1.1 原型、参数及返回值说明 1.1.1 原型: open()函数是Linux系统

    2024年02月12日
    浏览(48)
  • 【Linux】深入理解系统文件操作(1w字超详解)

    ❓是不是只有CC++有文件操作呢?💡Python、Java、PHP、go也有,他们的文件操作的方法是不一样的啊 1.1对于文件操作的思考: 我们之前就说过了: 文件=内容+属性 针对文件的操作就变成了对内容的操作和对属性的操作 ❓当文件没有被操作的时候,文件一般会在什么位置?💡

    2024年02月07日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包