本文主要介绍“如何调用Linux操作文件的底层系统”。在日常操作中,相信很多人对如何调用Linux操作文件的底层系统有疑惑。主机频道查阅了各种资料,整理出简单易用的操作方法,希望能帮你解决“如何调用Linux操作文件底层系统”的疑惑!接下来请跟着主机频道学习!
Linux操作系统奉行一切都是文件的理念,几乎所有的文件设备都可以通过一组系统调用来操作,即open()/close()/write()/read()。系统调用类似于C库调用操作文件。Linux自带的man手册是最权威的。通过查看手册来了解系统调用的用法。
代码& 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
成功:> = 0,即文件描述符;
Mode_t是一个类型别名,实际上是一个有符号整数。对于open函数,第三个参数仅在创建新文件时使用。
标志:打开标志
注意:这些实际上是定义好的宏。当需要使用多个参数时,使用按位or“|”形成多个标志参数。
它也可以与下列方法一起使用:
其他的就不一一介绍了,使用时需要自查。
写()
返回值:
如果成功,则为已写入的字节数;
如果误差为-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 * fdopen (intfd,constchar * mode),将文件描述符转换为文件指针;
Int fileno(FILE *stream),将文件指针转换成文件描述符;
Lseek函数函数:定位一个打开的文件。
off_t lseek(int fd,off_t offset,int where);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& ampmdashFILE* stderr,标准错误输出
这个程序默认开了三档,fd排第四,所以数字是3。
接下来,读取文件。
运行结果如下:
应用:通过读写复制文件。首先,我们声明我们不区分文本文件和二进制文件。
要复制一张图片,我们可以使用以下方案:
首先打开原始的二进制文件。
打开一个新文件。
从原始二进制文件中读取一部分,并将其写入一个新文件。
反复读写
停止读取,直到读完[read() == 0是循环停止的条件,不读取则结束]
完全复制
复制完成
打开文件后,fork的子进程可以和父进程共享同一个文件吗?
每次打开一个文件,我们都会在内核中生成一个struct文件来表示打开的文件,并记录以下信息:
文件偏移量(从0开始,文件指针随写入的数据偏移)
引用计数(多个进程正在使用此打开的文件)
Inode节点(存储流程的属性信息:谁创建了它,它的名称是什么,它存储在磁盘上的什么位置。通过这个inode节点,我们可以找到相应的具体文件)
打开模式:例如只读模式和只写模式。
测试1:在fork之前打开文件
Close(fd)写在最外面,父子进程会被关闭。每关闭一次,引用计数就会减1,直到为0。
运行结果如下:
原因如下:
测试2:在打开文件之前分叉
修改代码后,运行结果如下所示:
因为父进程和子进程分开了,它们打开了自己的文件,产生了自己的结构文件,并且不再共享文件偏移量。
在实际的应用场景中,我们更多的使用父进程打开的文件,子进程访问这个表单。
评论前必须登录!
注册