Linux相关概念和易错知识点(17)(文件、文件的系统调用接口、C语言标准流)

linux - 标准流 stdin、stdout、stderr;文件描述符fd git add test.txt 在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt到Git并且提交: rm test.txt 一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了: ... 阅读详情

目录

1.文件

(1)文件组成和访问

(2)文件的管理

(3)C语言标准流

(4)struct file

①文件操作表

②文件内核缓冲区

(5)Linux下一切皆文件

(6)file的管理(文件描述符表)

(7)struct files_struct

(8)总结图

2.文件的系统调用接口

(1)对文件的系统调用接口的理解

(2)open、close

①open

②close

(3)write、read

①write

②二进制文件和文本文件

③read

3.C语言标准流

(1)语言、硬件、系统描述

(2)引用计数在标准流上的使用

(3)语言封装库函数和流的意义


1.文件

(1)文件组成和访问

文件 = 内容 + 属性,空文件要占领磁盘空间,文件名、大小等属性这些都要被记录,只不过一般不会显示出来,这和进程类似(进程 = 数据和代码 + 属性)

打开一个文件的时候,是谁在访问呢?本质上文件是进程在访问。当程序跑起来并执行到打开文件的代码时(fopen、open等),系统才会去打开并加载文件。一个进程可以打开多个文件。

访问文件之前,必须先打开文件,为什么?因为文件没有被打开的时候在磁盘上。根据冯诺依曼体系结构,CPU不能直接访问磁盘,因此每次访问都要先打开文件,加载到内存当中。

因此我们可以总结出,打开文件 = 把文件(内容和属性)加载到内存中。当然不一定一次性全部加载,存在分批加载的处理。

(2)文件的管理

OS要不要管理加载到内存中的文件呢?必须要!

OS如何管理文件?和进程的管理一样都是先描述、再组织。内核中,被管理的文件 = 文件中的内核数据结构(文件的属性,使用struct保存) + 文件的内容,这类似管理进程的结构体struct PCB(PCB进程控制块,用于管理进程属性和数据代码)。因此,我们研究打开的文件本质上是在研究进程和文件的关系,管理文件本质上就是管理文件的数据结构!

那没有被打开的文件存在哪里呢?磁盘中。被打开的文件在内存中。没有被打开的文件肯定更多。

(3)C语言标准流

我们接下来通过C语言的三个流进一步理解文件。

stdin、stout、stderr分别叫标准输入流、标准输出流、标准错误流,典型的标准输入设备是是键盘,标准输出和错误设备是显示器。进程会默认打开三个流,这属于系统的特性,每种语言都要处理这种特性,尽管流的名字可能不同。

stdin、stout、stderr的类型都是FILE*,在Linux下一切皆文件,这三个流在底层都是文件(这三个流也叫文件流),FILE的本质是结构体,是用来描述文件的各种信息的。FILE属于stdio.h,是C语言封装的一个结构体,而并非系统内核描述文件的结构体,我们一定要分清。

在硬件侧,每种硬件都有自己的驱动程序(键盘、显示器、网卡、磁盘等),再往上层就是操作系统。操作系统是软硬件管理的系统。通过先描述、再组织的方法管理硬件,OS里面使用struct device描述硬件的信息,里面有type、id、status、vender等属性,也有来调用驱动程序的接口的函数指针,组织时通过调用结构体里面的函数指针来完成。所有device都通过指针连接在一起,形成一张描述硬件的链表struct device*。前面讲进程时我们也提过这个概念,当进程链入device里后进程会变成阻塞状态。

我们需要进一步深入,硬件都叫外设,不同设备有不同功能,比如键盘充当输入功能,显示器充当输出功能,网卡充当传输和接收功能。但所有设备都可以提取出共有属性,比如这些都有名字id、都有类型type、都有各自的供应商vender,只是这些属性的值不一样,device里面的一部分成员就提取了这些共有属性。但是外设的核心功能是IO(读写操作),不同设备的IO方法一定不相同,如显示器和网卡的写入方式不一样。device里面的具体输入输出函数指针名字不一样,如read_keyboard(),write_screen()。虽然像名字这些属性可以提取出来,但每个功能相关的函数各不相同(不统一命名为read()或write()考虑了可维护性和接口的设计等),怎么办呢?很多人会想为什么不能统一命名呢?既然device层无法统一,这就需要更上一层的封装了。这就是接下来要介绍的struct file。

(4)struct file

①文件操作表

操作系统有一种结构体struct file,里面有函数指针int (*read) (...),int (*write) (...)(简单的理解方式,实际上还会有单独的封装,不过底层原理一致),它们指向底层struct device里面的读写函数。通过file,我们不用关心device里面的方法名字是否相同,我们在struct file里调用封装的函数指针就可以了。这相当于在系统层面做了一层软件的封装,只要找到了file,就能访问硬件,这样一套系统叫虚拟文件系统vfs。

对于一般文件而言,当它们被加载到内存时,系统会直接创建struct file用来描述文件信息,其中读写信息系统会自动分配,而不是像硬件那样对device里面的方法做封装。

struct file类似多态,它是父类,struct device等是子类。在file侧它能调用的函数接口都长一样,但是实现了不同的功能(类似虚函数表,指向函数地址不同,但向上层提供的接口一致)。

简单来说,文件操作表就是函数指针的集合,将针对具体的文件能实现不同操作,并通过file的封装让硬件和文件划上了等号。

②文件内核缓冲区

我们设想一种情况,当我们想向硬件读入或写入时,数据会直接刷新到硬件中去吗?显然不会,因为系统的一切操作都是在存储器也就是内存里进行的,它的读写速度是比硬件的读写速度快很多的。因此在系统层面还有一个内核缓冲区,会先写入缓冲区,当缓冲区满了或是触发某些条件(如遇到\n了)再刷新到硬件中去。

这个内核缓冲区存在于file里面,每个file都有一个自己的缓冲区。当系统读文件或者写文件时都是向缓冲区进行的,OS会自主决定何时刷新缓冲区到硬件,何时读硬件。

(5)Linux下一切皆文件

如此一来,我们通过file可以统一访问普通文件和硬件。站在系统的层面来讲,普通文件和硬件都是文件,它们都被file集中描述起来了,这就是struct file存在的意义,这个时候我们也能理解为什么device侧没必要对读写方法做统一命名,因为file层面会做统一封装,将硬件和文件紧密联系起来,形成一个更大的文件的概念。系统调用文件操作时就是在file层面进行的,因此我们才会说Linux下一切皆文件。

(6)file的管理(文件描述符表)

之前我们遇到的PCB、struct device等都是按照链表的形式连接在一起的。但对于file而言就有弊端了。为了实现一些特殊的功能,如重定向、同一文件被多个进程使用等,file的管理需要一种更快速更高效的访问,就是顺序表。

顺序表要求数据集中,这显然对于文件来说太过苛责,每个file都不算小,扩容等操作难免效率低,因此采用指针数组struct file* fd_array[N],里面存着指向每个file的指针。如此一来,系统就可以通过struct file* fd_array[N]这一个数组管理所有文件,包括所有输入输出设备、硬件、文件等,它们通过file的封装使得系统可以无差别调用。

这就引入了文件描述符fd,fd就是指的struct file* fd_array[N]的下标,通过这个下标,我们可以找到file,进而进行文件操作。对于系统而言,这就是该进程使用文件的身份证,只有拥有fd,系统才能在struct file* fd_array[N]中找到file*,进一步找到file,进行读写操作。struct file* fd_array[N]也被叫做文件描述符表。

但是到这里还是有一个问题:我们研究打开的文件本质上是在研究进程和文件的关系,管理文件本质上就是管理文件的数据结构。后半句我们已深有体会,但前半句始终不明,struct file* fd_array[N]如何进一步被进程管理的呢?这就需要再上一层封装了。

(7)struct files_struct

单单一层struct file* fd_array[N]还是不足以管理好文件,首先我们还需要记录fd_array[N]这个数组的元素个数(也就是文件描述符的个数),并且同一个file可能被多个进程使用,比如几乎所有进程都会使用标准输入、标准输出、标准错误流。也有的文件只被一个进程使用。这就要用到引用计数了,当最后一个使用该文件的进程不再使用该文件时,就释放file,这显然需要每个进程的共同作用。并且还有一些文件相关的属性等也都需要单独维护,这就是files_struct干的事情了。struct files_struct里面存的就是struct file* fd_array[N]以及一些文件相关的属性,保证文件被很好地管理起来了。至此,我们的文件系统就搭建好了,struct files_struct以指针的形式交给PCB进行保管,每个进程都有struct files_struct* files,这也系统想要进行文件管理的入口。

(8)读取、写入、修改文件流程

当我们平时写文件时,系统都是先将内容write到文件内核缓冲区,再由OS自主决定调用找到file,file通过函数指针调用device的方法,最后写入文件里。系统自主刷新缓冲区这个过程性相对较慢,涉及硬件的IO都比较慢。这也是我们要手动保存文件的原因,因为我们写的数据都是写到缓冲区的,不勤加保存可能会导致意外时数据丢失。从用户端到硬件端输入的整个过程叫写入。

我们修改文件时也会这样处理。修改的本质也是先读取、再写入,就算只修改一个bit,系统也得先将数据加载到内存,我们进行内存级修改后再刷新回去。文件缓冲区存在的意义就是补平速度差异,操作系统也会在空闲的时候可能会预加载文件到缓冲区。这就是用空间换时间,毕竟硬盘是比内存慢的。

(9)总结图

系统的两大功能,一个进程管理,一个文件管理,两个功能解耦合。

2.文件的系统调用接口

我们在大致了解文件系统的框架之后,我们需要逐一深化刚才的知识点,首先就是对接口的理解

(1)对文件的系统调用接口的理解

我们常用的文件操作无非就是fopen、fclose、fputs、fgets、fwrite、fread、fscanf、fprintf等函数。这些函数都是C语言的库函数,它们都是语言级函数,语言级函数要对文件进行操作只能通过系统调用接口,也就是调用系统调用接口来实现。因此上述的所有函数都只是一个壳子,它的底层也是靠别人来完成的。这就是文件系统调用接口,open、close、write、read。这四个函数组合实现了上面所有函数的功能。

(2)open、close

open和close都是系统调用接口,是所有语言底层和系统调用接壤的接口,是C语言写的。

①open

返回值都是执行成功为fd,失败为-1。

第一个参数pathname(文件名,可带路径可不带),第二个参数int flag(32位int构成的位图)。其中标记位主要有:O_RDONLY(只读),O_WRONLY(只写),O_APPEND(追加),O_CREAT(创建),O_RDWR(读写),O_TRUNC(覆盖)。

标记位的本质是宏。每个标记位都是只有一个bit位为1的值并保证互相独立,使用O_RDWR | O_RDONLY传参使flag拥有组合属性,函数可按位与解析属性。如0001和0010的按位或就是0011,open函数拿到这个值后分别按位与1000、0100、0010、0001来解析原来的属性,如果按位与结果不是0就说明有该属性,会针对该属性进行处理。  

我们还发现open函数有个版本有第三个参数mode_t mode(权限,填0666取后三个指明权限)。注意,我们设置的mode要经过权限掩码umask。我们可以在程序中直接写umask(0)设置权限掩码。权限掩码也是针对当前进程的,执行程序会调用当前进程设置的新的权限掩码,同时不会影响父进程或已创建的子进程。如果要创建文件O_CREAT一定要写第三个参数,有文件的话写两个参数即可,调用时会根据传参个数来调用。

②close

返回值都是执行成功为fd,失败为-1。

close(fd)就是用文件描述符关闭文件。

我们发现fd是3,这是因为前3个分别被标准输入、输出、错误占领了。对于fd的分配来说,默认会分配fd_array中目前处于空位的最小的下标,这就意味着一个下标可以先后被多个文件使用。

这个例子实现的就是fopen("test.txt", "w")的功能。其中权限掩码要在open前设置,并且注意权限掩码是减去对应权限而不是单纯数字相减,要转换为权限的减法,例如在这里0333的x权限就是无效的,和0222效果一样。

(3)write、read

这两个函数可以实现包括printf等在内的所有关于文件读写的操作,它们作为系统调用接口有什么特别之处呢?为什么C语言要封装那么多函数呢?下面的展示会告诉我们答案。

①write

这个函数也是根据fd来寻找要写入的文件,buf是一个void*指针,最多写入count字节,ssize_t返回实际写入字节,一般来讲我们就根据自己要写的字节数传进去即可。

向文件写数据要注意不需要考虑\0,字符串以\0结尾是C语言要求,不是文件的规范,写进去其实算是乱码,会影响我们的预期效果。

write还有另一个特性

我们直接向文件里面写入了二进制数据!

这是一个很需要我们仔细体会的地方,很考验我们对源码的理解,这也涉及到二进制文件和文本文件的理解。

②二进制文件和文本文件

在上面的例子中,int msg的32位数据里只用到了前几位,剩下的都是0。我们直接将这个整数的指针传过去并写入1个字节,就相当于将前8个bit写了进去(系统调用接口会根据字节序同步处理处理,注意数组存储顺序是从低地址到高地址,和字节序没关系)。这个时候文件里面就有了96对应的二进制。当cat读取文件内容时,二进制会被通过ASCII码转为a,最终呈现在我们眼前。为什么会有ASCII码的转换步骤呢?为什么读取出来不是97呢?

这里需要引入格式化的概念。我们打印内容到显示器文件时,我们向显示器写的其实是一个一个字符,显示器是字符设备。因此当我们打印整型97时,显示的确实是97,但对于显示器来讲是"97"这个字符串,这就意味着我们用的printf("%d", 97)是帮我们将整型转为了字符,%d就是一套转换的标准,包括%lf这些都可理解为帮助我们格式化为字符串的“选项”。在源码上来讲,显示器得到的早就不是源码97对应的二进制了,而是'9'、'7'两个字符对应的ASCII码对应的二进制。同理,当我在键盘里输入1234,我们最初得到的也是字符,也需要scanf系列函数格式化输入转为%d。

计算机底层文件都是二进制,区分它们是不是文本文件的关键就在于是否经历格式化这个步骤。对于文本文件而言,一切内容都需要经过ASCII编码才能存储,以文本文件的形式读入时也需要经过ASCII的转换才行,这都是在软件层进行转换的。

对于二进制文件而言,就是直接转换为二进制写入。int直接按照内存中int的源码形式直接写入文件,包括浮点等都是如此。这就是为什么上面write的第二个参数是void*的原因,write只需要拿到地址开头和读取长度,当输入"Hello"时当然没问题,因为它不需要转换,它本身的源码形式就是ASCII转换的文本形式,所以虽然write以二进制的形式写入,但读取依然正常;而当输入int、float时,write会直接将它们的源码写进文件。当我们用文本文件来读二进制文件时,它会自动用ASCII转换一次,因此我们存的97,文件中确实存的就是97的二进制,但读入时是文本文件的格式,ASCII转换过来就是字母a。

所以一般情况下文本文件读二进制文件都是乱码,就是多了一次格式化的过程。在硬件层根本不存在二进制文件和文本文件。而对于系统调用接口write和read而言,它们都是以指针和字节数为基准,按照二进制的形式直接读写。文本文件和二进制文件的区分要到上层软件层才能区分出来。

这就是为什么会有一系列printf、scanf函数的原因。它帮我们格式化总比我们自己格式化方便很多,并且要理解到这一点需要前期很多的计算机知识,对入门来讲很不友好。

③read

用法和write一致,参数等含义都一致。

如果我们想要读之前写的内容,还可以lseek来定位指针到最前面,不然read只会向后读,读不到我们之前写的内容。

read的底层也都是以二进制形式直接将源码填到我们传过去的指针对应的空间里。所以我们只能用char的数组来接收,且当存储时是以字符形式(文本形式)进行时才能保证正常解析。

从上面write和read的讲解中,我们应该能够很自然的理解fwrite和fprintf之间的区别了,也能很清晰地明白它们的底层调用是什么,以及为什么要上层封装。

3.C语言标准流

前面我们靠C语言标准流帮助我们理解了文件,现在我们要重新认识标准流了。

(1)语言、硬件、系统描述

前面我说过进程会默认打开三个流,这属于系统的特性,每种语言都要处理这种特性,尽管流的名字可能不同。什么意思呢?stdin、stdout、stderr是语言级描述,每种语言都有自己的一套叫法;键盘、显示器是硬件层面上的描述,进程会默认去打开对应硬件的流;fd是系统找文件的身份证,因此0、1、2是系统级描述。

这三个描述紧密相连,stdin、stdout、stderr的类型都是FILE,这也是一个结构体,属于语言上的描述。语言的底层就是系统,FILE的描述信息里就有对应文件的fd,即_fileno成员。只有通过_fileno才能通过语言级描述转为系统级描述,系统再通过fd找到file,最终file转为对硬件的描述,这样一个读写流程才能完成。

(2)引用计数在标准流上的使用

默认情况下输入、输出、错误流分别占据fd_array[N]的前三个下标。所有进程都会使用这三个file,因此files_struct上的引用计数很有用处,一个file可以被好几百个进程指向,这极大地节约了空间,不用每次都针对每个进程重新创建file了。

就算该进程关闭了输入流,但是这只会修改这个进程的fd_array并对files_struct的引用计数--,实际上输入流对应的file依然没有关闭,因为进程之间具有独立性,对一个进程的操作不会影响其他进程。

(3)语言封装库函数和流的意义

C语言为什么要封装呢?换句话说,为什么每个语言都要封装自己的流呢?

这就是对跨平台、可移植性的考虑了。如果运行代码的平台换了,在Windows、MacOS、Linux之间互相切换,由于不同系统的调用接口不一样,比如在某个系统open函数参数有差别,这时我们如果不封装上层fopen、fprintf这些函数,也不封装FILE,而是直接使用open等系统调用接口的话,我们的代码就跑不了,流都没法打开。因此要提高语言的可移植性、提高跨平台性,就必须对那些兼容性较差的部分做封装。我们上层的使用库函数和FILE的代码不需要改,动的是代码底层调用,这只需要我们选择对应安装包就可解决。

对于C语言来说,fopen、fclose、printf的具体实现在glibc库(C标准库)里面,里面有语言的源代码。源文件有不同版本,源代码在编译时也会按照不同系统编译,Linux版、Windows版、MacOS版,安装环境也需要根据不同系统安装。这一点相信我们在配置环境时都遇到过,这也解释了为什么我们要根据自己的系统选择对应版本的安装包。这在系统层面是关键问题。
 

别再只会用Excel了!Minitab 21手把手教你搞定SPC控制图(从数据导入到结果解读) 本文详细介绍了如何使用Minitab 21高效制作SPC控制图,从数据导入到结果解读的全流程。通过对比Excel的局限性,展示Minitab在自动化计算、图表标准化和特殊原因检验等方面的优势,帮助质量管理人员提升工作效率和数据分析专业性。 阅读详情

相关推荐

【Unity报错】Unity导入海康SDK 报错 DllNotFoundException: PlayCtrl assembly

2.尝试按网上其他的办法(包括使用depengs查看dll依赖等)1.先检查Plugins文件夹中是否存在PlayCtrl文件。3.如果网上查阅的办法都不能解决,请继续往下看。更换低版本的SDK库文件。

weixin_42968584的博客 1126

使用Linux虚拟文件系统中的open、read、close接口对某一文件进行读取操作

1、创建读取函数文件,文件名称testopen.c 如下: #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<string.h> int main() { int fd; int rc; char buf[512] = {0}; fd = open("re

qq_33767353的博客 4055

提高机器学习模型准确率的八大方法

原文连接:http://www.techweb.com.cn/network/system/2016-01-27/2269274.shtml 此文仅是一个小品文,详细理论请读论文,参考书籍。 前言:我的概述 机器学习面对的是一个受限有穷空间 到 一个扩大的有穷空间 的泛化问题。若假设空间足以覆盖真实的数据空间,机器学习方法可以弃之不...

alppkk4545的博客 1301

linux中的文件IO==Linux应用编程1

1、与文件IO的区别(1)标准IO是C库函数,文件IO是API。(2)C库函数是由API封装而来的,比API好用。(3)C库函数具有可移植性而API不具有可移植性。(4)性能和易用性上,C库函数要好一些,譬如IO,文件IO是不带缓存的,而标准IO是带缓存的,因此标准IO比文件IO性能更高。2、常用标准IO函数介绍3、简单的标准IO读写示例0};\n");https。...

栋哥修炼日记 658

数理金融学笔记 Chap2 二叉树模型Binomial

2 二叉树模型与期权定价 Binomial Model and Option Pricing 文章目录2 二叉树模型与期权定价 Binomial Model and Option Pricing单期二叉树模型 One-step Binomial Model风险与无风险资产单期二叉树模型与无套利条件无套利定价 No Arbitrage Pricing风险中性定价 Risk Neutral PricingDelta套期保值 Delta Hedging两期二叉树模型 Two-Step Binomial Model

weixin_66831131的博客 2387

小米万兆路由器里的Docker安装可道云(Kodexplorer)私有网盘

小米2022年12月份发布了万兆路由器,里面可以使用Docker。 今天尝试在小米的万兆路由器里安装[可道云](http://kodcloud.com/)(Kodexplorer)私有网盘。

engchina的专栏 1万+

Linux——操作文件的系统调用(open、write、read、close)

返回值:ssize_t :实际写入了多少个字节;返回值:ssize_t :实际读取了多少个字节;标准错误输出对应的编号:2 stderror。buf:把文件内容读取到一块空间buf中。O_TRUNC:清空文件,重新写入;WIFEXIRED:正常退出的状态。标准输入对应的编号:0 stdin。标准输出对应的编号:1 stdout。O_CREAT:文件不存在则创建;fd:对应打开的文件描述符。O_APPEND:文件末尾追加;count:期望要读取的字节数。buf:写入的文件内容。O_WRONLY:只写打开;

x20020402的博客 2257

【数字电源/MATLAB+PLECS】如何进行 Buck 数字电源仿真(二)PLECS 搭建开环 Buck 功率级

本文介绍了如何在PLECS中搭建开环Buck功率级模型,验证数字电源设计的基本思路。重点内容包括: 明确开发顺序:先开环验证功率级,再闭环设计控制器 搭建关键组件:输入电源、PWM模块、MOSFET开关、续流二极管、LC滤波电路及负载 设置初始参数:24V输入、12V输出、200kHz开关频率、22μH电感、100μF电容 测量关键波形:MOSFET Vds验证开关动作、电感电流纹波和输出电压稳态值 提供完整仿真模型和GitHub资源,便于读者复现验证 文章强调通过开环测试先确保功率级正确性,为后续闭环控制

weixin_43234123的博客 1218

文件I/O操作open(),close(),read()和write()函数详解

1. open()函数 功能描述:用于打开或创建文件,在打开或创建文件时可以指定文件的属性及用户的权限等各种参数。 所需头文件:#include ,#include ,#include 函数原型:int open(const char *pathname,int flag

4271

视觉语言模型在三维导航中的应用:JanusVLN项目解析与实战

视觉语言模型(VLM)作为多模态人工智能的核心技术,通过融合视觉感知与自然语言理解能力,实现了对开放世界场景的语义化解析。其原理在于利用预训练的视觉编码器和大型语言模型,将图像信息映射到与文本对齐的语义空间,从而完成跨模态的推理与生成。这一技术为机器人自主交互、智能家居控制等场景提供了基础能力支撑,尤其在需要理解复杂指令并执行序列决策的任务中展现出巨大价值。本文聚焦于视觉语言导航(VLN)这一具体应用,探讨如何通过架构创新与高效微调策略,将通用VLM适配到三维仿真环境中的导航任务,并以JanusVLN项目为

weixin_30240349的博客 669

Claude Code、Codex、Gemini CLI、OpenCode 和 OpenClaw 配置管理太麻烦?试试这个统一管理工具

还在为 Claude Code、Codex、Gemini CLI 等 AI CLI 配置烦恼?🤯 这款桌面工具支持五大助手统一管理,一键切换 50+ 服务商,MCP 和 Skills 集中管理 🛠️,跨平台支持,让你的 AI 编程更高效 ⚡

XiaoqiangClub的博客 913

Linux文件系统学习(四)之read open系统调用

open read 系统调用过程

阿罗 4874

FPGA开发中的操作系统

在FPGA开发中,操作系统起着关键的作用,它负责任务管理、资源管理、中断处理和设备驱动程序等功能。在实际的FPGA开发中,可以选择使用现有的操作系统,如MicroC/OS-II、FreeRTOS等,或者根据具体需求自行设计和开发操作系统。在FPGA(可编程逻辑门阵列)开发中,操作系统扮演着关键的角色,为硬件设计师提供了一种有效的方式来管理资源、调度任务并实现系统级功能。本文将介绍FPGA开发中的操作系统概念,并提供一个简单的示例代码来说明如何在FPGA平台上实现一个基本的操作系统。

CqpFsharp的博客 1156

【Linux课程学习】:文件第一弹---文件基础(文件描述符的底层设计)

这篇主要谈论的是关于文件的基础,让我们在接下来能更好的理解文件描述符,系统调用的相关的文件函数,和语言层封装的f系列的函数。对于这篇文章,会从C语言文件接口,C语言默认打开的三个输入输出流,认识系统文件调用接口,这几个方面介绍文件,打好基础。

路虽远,行则将至!事虽难,做则必成! 5439

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

[操作系统] 基础 IO:理解“文件”与 C 接口

本文从狭义与广义两方面深入探讨了 Linux 中的“文件”概念,阐释了文件操作的分类及系统底层实现——包括文件描述符、inode、缓冲机制等。随后,通过 hello.c 案例详细回顾了 C 语言文件接口的使用方法,从文件的打开、写入、读取,到如何利用各种标准流(stdin、stdout、stderr)输出信息,以及不同的文件打开模式。希望本文能为大家在 Linux 基础 IO 学习及 C 语言文件操作实践中提供清晰的指导和帮助。

kevin_blog 1184

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Linux基础I/O:C语言文件操作“黑话”指南:读懂文件描述符的摩斯电码

我们在背景知识中说过要想对文件的内容进行操作,那么首先要做的就是打开文件,所以说上面的“ > ”在底层实现中同样也是和上面的w一样,清空文件,在将内容写入到文件中,他们的底层实现都是通过系统调用实现的,这点下面我们就会讲到。当然呢,关于文件的操作不止有w和a,除了这俩还有上面的一些,这里我没有讲r,因为r就是读文件,没什么可讲的,并且它也不是我们讲的重点,而剩下的后面有+号的都是既可以读又可以写的方式,为什么这些我没有讲呢?但是当我们再次执行后查看文件中的内容,发现我们新增的内容没有了,这是怎么回事呢?

2301_80236968的博客 1910

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Linux系统编程学习 NO.13—— 文件的概念、文件操作接口、fd、文件重定向、VFS原理

本篇文章介绍了操作系统文件的相关概念,如C语言的文杰操作接口、Linux的文件操作系统调用接口、重定向原理和操作、以及谈了谈Linux如何做到一切皆文件。

sinzz的博客 1110

【Linux】文件IO深度解析:文件描述符与重定向的奥秘

详细介绍了linux中系统文件IO以及文件描述符重定向的知识

You build it, you run it 2697

Linux 文件 IO:从概念到系统调用

本文系统介绍了Linux文件系统的核心概念与操作机制。首先阐述了Linux文件模型"文件=inode+数据块"的基本原理,指出目录通过文件名到inode号的映射实现文件关联。从物理层面分析,文件操作本质是对磁盘设备的I/O操作,操作系统通过封装硬件复杂性提供统一接口。重点讲解了"一切皆文件"的设计理念,将硬件、进程等资源抽象为文件,通过虚拟文件系统(VFS)实现统一访问。详细剖析了文件描述符(fd)机制,包括其作为进程打开文件表索引的本质、分配规则及生命周期管理。深入

有且仅有质量分95以上的博客 929

Linux:基础IO---文件描述符

文件分为程序文件和数据文件文件名 == 文件路径+文件名主干+文件后缀数据文件:文本文件二进制文件流:我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。C程序针对文件、画面、键盘等的数据输⼊输出操作都是通过流操作的。⼀般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作。

知北游天的博客 1017

【Linux取经路】基础I/O之被打开的文件——文件描述符的引入

本篇文章首先对C标准库中和文件有关的接口进行了回顾,接下来介绍了和文件有关的系统调用,得出结论,C标准库的文件接口本质上在底层都封装了系统调用。最后讲解了访问文件的本质,引入了文件描述符的概念,揭示了进程和文件之间的关系。

春人.的博客 3670

Linux基础文件IO(上)(16)

之前我们在学习过程中遇到了重定向,这是什么原理?文件的写入读取又是什么样的?下面就由我来为大家讲解!!!很精彩,有时候学着学着你就会有一种融会贯通的感觉!!!我们知道,当 fopen 以写入的方式打开一个文件的时候,若该文件不存在,则会自动在当前路径下创建该文件,那么这里所说得 “当前路径” 到底是什么意思呢?例如,我现在在BasicIO目录下运行可执行程序 myproc.exe ,那么该可执行文件所创建的 “log.txt” 文件会出现在BasicIO 目录下。

tan180°的博客 822

【C语言】《C 文件操作从入门到精通:标准流、FILE*、fseek 与缓冲区机制》

从程序设计的角度,文件分为程序文件和数据文件函数名功能适用于fgetc字符输入函数所有输入流fputc字符输出函数所有输出流fgets文本行输入函数所有输入流fputs文本行输出函数所有输出流fscanf格式化输入函数所有输入流fprintf格式化输出函数所有输出流fread二进制输入文件输入流fwrite二进制输出文件输出流上⾯说的适⽤于所有输⼊流⼀般指适⽤于标准输⼊流和其他输⼊流(如⽂件输⼊流);

2501_93351213的博客 874

【Linxu基础IO】文件 && 文件操作 && 虚拟文件系统(VFS)

文件操作在Linux系统编程中相当重要,也是Linux系统编程的基础,本文将向大家介绍Linux中基础IO接口的使用、文件、标准流、等相关概念,来帮助你快速了解并熟悉文件操作;先来回忆一下C语言中的文件操作;return 1;文件打开方式有很多,可使用 man fopen 自行查看r+以读的方式打开(文件必须存在)w以写的方式打开(如果文件存在清空文件,如果不存在会创建文件)r+以读写的方式打开(文件必须存在)w+以读写的方式打开(文件不存在会新建文件,文件存在时进行写入会清空文件)

2202_75605090的博客 1419

Linux系统篇(十七)——文件(一):文件 IO 深度剖析:从标准流、系统调用到内核底层全貌拆解

维度标准库 FILE 流 (fopen/printf)系统调用 (fd/open/write)操作对象FILE*流指针int文件描述符 fd缓冲机制用户态自带缓冲区,减少系统调用无用户缓冲,直接交互内核可移植性跨平台(Windows/Linux 通用)Linux/Unix 专属,不可跨平台使用场景上层业务、简单打印、通用程序嵌入式、底层服务、重定向、高性能 IO依赖头文件stdio.hfcntl.hunistd.h。

2502_94387000的博客 604

从基础到本质:文件 IO 操作全解析

目录"文件"的理解文件操作的归类认知回顾C语言的文件接口打开文件写文件读文件输出信息到控制台stdin & stdout & stderr打开文件的方式wa狭义理解文件在磁盘里,磁盘是永久性存储介质,因此文件在磁盘上的存储是永久性的。如果文件大小为0,文件要不要在磁盘上占据空间呢?要的,文件=内容+属性。广义理解在前面我们提到,Linux下一切皆文件(键盘、显示器、网卡、磁盘…… 这些都是抽象化的过程)。系统角度对文件的操作本质是进程对文件的操作,磁盘的管理者是操作系统。文件的读写本质不是通过C语言/C++

2302_79376097的博客 1903
上一篇: Linux相关概念和易错知识点(16)(Shell原理、进程属性和环境变量表的联系)
下一篇: Linux相关概念和易错知识点(18)(重定向、语言级缓冲区)
-SGlow-
博客等级 码龄3年 1513粉丝 118原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值