本文主要介绍“如何调用Linux操作文件的底层系统”。在日常操作中,相信很多人对Linux操作文件的底层系统如何调用有疑惑。主机频道查阅了各类资料,整理了简单易用的操作方法,希望能帮助大家解决“Linux操作文件底层系统如何调用”的疑惑!接下来,请跟随主机频道一起学习吧!
Linux操作系统奉行一切都是文件的理念,几乎所有的文件设备都可以通过一组系统调用来操作,即open()/close()/write()/read()。系统调用类似于C库调用操作文件。Linux附带的手册是最权威的。查看手册,了解系统调用的用法。
代码& ampmdash& ampmdash表征的意义
1 & ampmdash& ampmdash用户可以在shell环境中操作/执行的命令。
2 & ampmdash& ampmdash系统内核可以调用的函数和工具
3 & ampmdash& ampmdash一些常用的函数和函数库,大部分C函数库。
4 & ampmdash& ampmdash设备文件的描述,通常是/dev下的设备。
5 & ampmdash& ampmdash配置文件或某些文件的格式。
6 & ampmdash& ampmdash比赛
7 & ampmdash& ampmdash管理和协议,如Linux文件系统、网络协议等。
8 & ampmdash& ampmdash系统管理员可用的命令
9 & ampmdash& ampmdash内核相关文件
请注意,在Linux中,系统头文件通常存储在/usr/include目录中;下面包含的一些头文件有sys,它们实际上是include下子目录中的头文件。
open()& amp;mdash& ampmdash打开或创建文件
返回值类型:int &;mdash& ampmdash文件描述符fd,每次打开一个文件,都会得到一个文件描述符。这个文件描述符是可塑的,我们可以通过文件描述符进行读写。
失败:-1
success:》= 0,即文件描述符;
Mode_t是一个类型别名,它实际上是一个有符号整数。对于open函数,第三个参数仅在创建新文件时使用。
标志:开放标志
注意:这些实际上是定义的宏。当需要使用多个参数时,使用按位或“|”形成多个标志参数。
它也可以与以下方法一起使用:
其他的就不一一介绍了,使用时需要自查。
写()
返回值:
如果成功,则是已写入的字节数;
如果错误为-1;
注意:当计划写入的字节数不等于函数返回值时,说明写入有错误,可以用来检查写入是否成功;
参数:
Fd:写入文件的文件描述符;
Buf:用于存储要写入的数据的缓存;
Count:写一次数据所需的字节数;
注意:
对于普通文件,写操作从文件的当前位移开始。如果在打开文件时指定了O_APPEND选项,则在每次写操作之前会在文件的当前结尾设置文件位移。成功写入后,文件位移会增加实际写入的字节数。
read()
返回值:读取的字节数。
如果文件结尾为0;如果错误为-1;
参数
Fd:读取文件的文件描述符;
缓冲器:用于存储读取数据高速缓存;
Count:需要读取一次的数据的字节数;注意,返回值是实际读取的字节数,这是不一样的;
注意:读取操作从文件的当前位移开始,在成功返回之前,位移增加实际读取的字节数(这个位移可以自己设置);
close()
注意:当一个进程终止时,它打开的所有文件都会被内核自动关闭。
注意:这些没有缓存的函数是内核提供的系统调用;这与我们在C语言中学习的那些IO操作完全不同。它们不是标准C的一部分,而是POSIX的一部分。
标准C通过操作文件的结构指针来操作文件,这里使用了文件描述符。
文件描述符的范围是0 &;mdash& ampmdashOPEN MAX,Unix早期采用的上限是19个(即每个进程允许打开20个文件),但现在许多系统将增加到63个,Linux将增加到1024个,可以在
文件描述符和文件指针
file * FD open(intfd,constchar * mode),它将文件描述符转换为文件指针;
int fileno(FILE * stream),它将文件指针转换为文件描述符;
Lseek函数函数:定位一个打开的文件。
off _ t lseek(int FD,off_t offset,int why);Fd:已经打开的文件描述符;
偏移:位移;
Whence:定位的位置,即参考点。
SEEK_SET:将文件的位移设置为从文件开头偏移字节;
SEEK_CUR:将文件的位移设置为其当前值加上偏移量,偏移量可以是正数也可以是负数;
SEEK_END:将文件的位移量设置为文件的长度加上偏移量,可以是正数,也可以是负数(如果此时为正数,则涉及空文件,请参见下面的解释);
返回值:* *如果成功,将返回一个新的文件位移(绝对位移)* *如果错误,将为-1;当导航到文件末尾时,可以返回文件的大小;
lseek函数还可以用于确定所涉及的文件是否可以设置位移。如果文件描述符引用管道或FIFO,则lseek返回-1并将errno设置为EPLPE;
空文件的示例:
# include & ltstdio.h & gt
# include & ltfcntl.h & gt
# include & ltstring.h & gt
# include & ltstdlib.h & gt
# include & ltunistd.h & gt
# include & lt错误号& gt
//生成一个空文件
char * buffer = & quot0123456789 & quot;
int main(int argc,char *argv
我们可以看到,在使用more命令查看文件内容时,发现显示的内容只写入一次,并且使用了od。
-c命令检查文件的ASSCI代码,我们会发现两个内容之间有10 \ 0,这是空的。当您使用vim打开文件内容时,还可以看到有10个@符号。
注意:每个文件都有一个与之相关的“当前文件偏移量”,它是一个非负整数,用于测量从文件开头开始计算的字节数。通常,读取和写入操作从文件的当前偏移量开始,并按读取或写入的字节数增加偏移量。默认情况下,打开文件时,除非指定O_APPEND选项,否则文件的位移设置为0;
示例:
运行结果如下:
fd = 3的原因是:
系统内部的PCB中有一个文件表来记录打开的文件,文件描述符实际上就是文件表的下标。
0 & ampmdash& ampmdash文件*标准输入,标准输入
1 & ampmdash& ampmdash文件*标准输出,标准输出
3 & ampmdash& ampmdash文件*标准错误,标准错误输出
这个程序默认打开了三个文件,fd排在第四位,所以数字是3。
接下来,读取文件。
运行结果如下:
应用:通过读写复制文件。首先,我们声明我们不区分文本文件和二进制文件。
要复制图片,我们可以使用以下方案:
首先打开原始二进制文件。
打开一个新文件。
从原始二进制文件中读取一部分并将其写入新文件。
反复读写
停止读取直到完成【read()= = 0是循环停止的条件,如果没有读取,则完成】
完全复制
复制完成
打开文件后,fork的子进程可以与父进程共享同一个文件吗?
每当我们打开一个文件时,我们将在内核中生成一个结构文件来表示打开的文件并记录以下信息:
文件偏移量(从0开始,文件指针随写入数据偏移)
引用计数(多个进程正在使用此打开的文件)
Inode节点(存储进程的属性信息:创建者、名称以及在磁盘上的存储位置。通过这个inode节点,我们可以找到相应的特定文件)
打开模式:例如只读模式和只写模式。
测试1:在fork之前打开文件
close(FD)写在最外侧,父子进程将被关闭。每次关闭它时,引用计数将减少1,直到它为0。
运行结果如下:
原因如下:
测试2:在打开文件之前分叉
修改代码后,运行结果如下所示:
因为父进程和子进程分开了,它们打开了自己的文件,产生了自己的结构文件,并且不再共享文件偏移量。
在实际应用场景中,我们使用父进程打开的更多文件,子进程访问该表单。
评论前必须登录!
注册