Linux之file_struct&fd(file descriptor)
2017-05-11 10:23
381 查看
Linux中每个进程会产生一个PCB(Process Control Block)进程控制块,既然是一个进程,那么就会在这个进程中对文件进行操作,所以每个PCB中会对应生成一个struct file(文件描述符表),直观的看。每个位置都对应一个指针指向目标文件。这个位置使用open函数来确定的。
其中char*的pathname代表的时文件的路径和名称;
flags代表的是打开文件的方式,且flags是以int(整型)数据的32比特位表示,所以可以传入多个参数。
例如:O_WRONLY|O_CREAT:表示以只写方式打开并创建文件(注意中间的’|’符号)。
参数选项:
mode:表示创建完成的文件的权限,可以直接传入8进制数字,例如:400
返回值:即表示当前操作成功之后系统分配的文件描述符。
但是,默认情况下,系统默认:0号下标代表stdin;1号下标代表stdout;2号下标代表stderr。
创建新文件时会将系统中未使用的最小的文件描述符传给返回值,一般情况下,因为0/1/2已经用过,所以第一个文件的文件描述符都为3。
但是若手动关闭0或1或2号文件流,则会选择最小的。
例:
则此时创建的文件最小的是0,接下来是2,然后才是3,即fd1=0,fd2=2。
open函数的返回值就是在文件描述符表中确定文件位置的数据。
它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码中。
struct file的指针通常被命名为file或filp。其有两个非常重要的字段:文件描述符和缓冲区。
文件描述的产生和作用在上文已经阐述的很清晰了,它和struct file的关系如下图所示
这样就很清晰了。
无缓冲:一般在在执行系统调用的情况下采用,指的是标准I/O不对字符进行缓冲存储,标准库中的stderr就是采用无缓冲式,保证只要有错误出现就输出。
行缓冲:系统在执行I/O操作涉及到终端时,就会采用行缓冲。在遇到换行符’\n’时,输入/出之前缓冲区的所有字符。
全缓冲:这种情况只有在缓冲区全部写满之后才会冲洗缓冲区。对于驻留在磁盘上的文件来说通常是由标准IO库实施全缓冲。
输入/输出重定向:
重定向:本质上是修改文件描述符的内容
‘>’:输出重定向
‘>>’:追加重定向
‘<’:输入重定向
例:echo “hello world!\n” > world.txt
则会将hello world重定向到world.txt文件中
重定向也可以理解为:在将需要将输出的数据保存在一个文件里面时,创建一个文件,但这个文件此时对应的file_struct中的下标并不是最小且未使用的,而是1号下标。这是因为系统只认文件描述符的原因,所以重定向就是替换file_struct中1号下标的指向,使其指向新创建的保存数据的文件,而已经不是stdout了。所以,使用echo “hello world!\n” > world.txt时,’>’就相当去替换1号下标的指向。所以最终不是输出在显示器上,而是保存在文件里。
几个函数的冲洗缓冲区的方式:
printf、fwrite等一些库函数在正常且正确的将需要操作的数据操作完毕后,是不会“管理”缓冲区的,所以此前缓冲区中的数据还留在缓冲区中,如果将当前进程创建出一个子进程,且将函数输出重定向到一个文件中,就会发现本来子进程中什么也没干,但是在子进程的区域还是会有printf、fwrite等库函数操作的数据,这是因为在之前printf、fwrite等库函数操作完数据后,并没有冲洗缓冲区,导致缓冲区还存在数据,此时的子进程因为采用写时拷贝使用父进程的数据,所以此时也会给自己拷贝一份。
file struct中的其他成员:
mode_t f_mode:文件模式确定文件时可读、可写或者可读写的的,通过位FMODE_READ和FMODE_WRITE,在open函数中检测这个成员的读写状态时,不需要检查读写许可。
loff_t f_pos:当前读写位置,在所有平台都市64位,每次读、写后更新这个指针,但需要注意的是,llseek方法可以改变这个指针的指向。
unsigned int f_flags:文件标志。例如:O_RDONLY, O_NONBLOCK, 和 O_SYNC。
struct file_operations * f_op:和文件关联的操作。
void* private_data:open系统电调用设置这个值为NULL,在为open调用系统调用前,你可自由的使用或者忽略这个成员。在系统调用间保留状态信息。
struct denrty* f_dentry:关联到文件的目录入口( dentry )结构。
其他成员的详细请戳:http://blog.sina.com.cn/s/blog_7943319e01018m3w.html
open函数
open函数的原型为:int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
其中char*的pathname代表的时文件的路径和名称;
flags代表的是打开文件的方式,且flags是以int(整型)数据的32比特位表示,所以可以传入多个参数。
例如:O_WRONLY|O_CREAT:表示以只写方式打开并创建文件(注意中间的’|’符号)。
参数选项:
O_RDONLY--只读--00 O_WRONLY--只写--01 O_RDWR--读写--10 O_CREAT--创建--100
mode:表示创建完成的文件的权限,可以直接传入8进制数字,例如:400
返回值:即表示当前操作成功之后系统分配的文件描述符。
但是,默认情况下,系统默认:0号下标代表stdin;1号下标代表stdout;2号下标代表stderr。
创建新文件时会将系统中未使用的最小的文件描述符传给返回值,一般情况下,因为0/1/2已经用过,所以第一个文件的文件描述符都为3。
但是若手动关闭0或1或2号文件流,则会选择最小的。
例:
close(0); close(2); int fd1 = open ("myfile1.txt",O_WRONLY|O_CREAT, 600); int fd2 = open ("myfile2.txt",O_WRONLY|O_CREAT, 600);
则此时创建的文件最小的是0,接下来是2,然后才是3,即fd1=0,fd2=2。
open函数的返回值就是在文件描述符表中确定文件位置的数据。
struct file
struct file结构体定义在include/linux/fs.h中定义。文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的 struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码中。
struct file的指针通常被命名为file或filp。其有两个非常重要的字段:文件描述符和缓冲区。
文件描述的产生和作用在上文已经阐述的很清晰了,它和struct file的关系如下图所示
这样就很清晰了。
缓冲区
系统中共存在三种缓冲区:无缓冲,行缓冲,全缓冲。无缓冲:一般在在执行系统调用的情况下采用,指的是标准I/O不对字符进行缓冲存储,标准库中的stderr就是采用无缓冲式,保证只要有错误出现就输出。
行缓冲:系统在执行I/O操作涉及到终端时,就会采用行缓冲。在遇到换行符’\n’时,输入/出之前缓冲区的所有字符。
全缓冲:这种情况只有在缓冲区全部写满之后才会冲洗缓冲区。对于驻留在磁盘上的文件来说通常是由标准IO库实施全缓冲。
输入/输出重定向:
重定向:本质上是修改文件描述符的内容
‘>’:输出重定向
‘>>’:追加重定向
‘<’:输入重定向
例:echo “hello world!\n” > world.txt
则会将hello world重定向到world.txt文件中
重定向也可以理解为:在将需要将输出的数据保存在一个文件里面时,创建一个文件,但这个文件此时对应的file_struct中的下标并不是最小且未使用的,而是1号下标。这是因为系统只认文件描述符的原因,所以重定向就是替换file_struct中1号下标的指向,使其指向新创建的保存数据的文件,而已经不是stdout了。所以,使用echo “hello world!\n” > world.txt时,’>’就相当去替换1号下标的指向。所以最终不是输出在显示器上,而是保存在文件里。
几个函数的冲洗缓冲区的方式:
printf、fwrite等一些库函数在正常且正确的将需要操作的数据操作完毕后,是不会“管理”缓冲区的,所以此前缓冲区中的数据还留在缓冲区中,如果将当前进程创建出一个子进程,且将函数输出重定向到一个文件中,就会发现本来子进程中什么也没干,但是在子进程的区域还是会有printf、fwrite等库函数操作的数据,这是因为在之前printf、fwrite等库函数操作完数据后,并没有冲洗缓冲区,导致缓冲区还存在数据,此时的子进程因为采用写时拷贝使用父进程的数据,所以此时也会给自己拷贝一份。
file struct中的其他成员:
mode_t f_mode:文件模式确定文件时可读、可写或者可读写的的,通过位FMODE_READ和FMODE_WRITE,在open函数中检测这个成员的读写状态时,不需要检查读写许可。
loff_t f_pos:当前读写位置,在所有平台都市64位,每次读、写后更新这个指针,但需要注意的是,llseek方法可以改变这个指针的指向。
unsigned int f_flags:文件标志。例如:O_RDONLY, O_NONBLOCK, 和 O_SYNC。
struct file_operations * f_op:和文件关联的操作。
void* private_data:open系统电调用设置这个值为NULL,在为open调用系统调用前,你可自由的使用或者忽略这个成员。在系统调用间保留状态信息。
struct denrty* f_dentry:关联到文件的目录入口( dentry )结构。
其他成员的详细请戳:http://blog.sina.com.cn/s/blog_7943319e01018m3w.html
相关文章推荐
- linux设备驱动第三版笔记---->linux驱动重要数据结构之struct file
- linux中文件描述符fd和struct file结构体的释放
- linux中文件描述符fd和struct file结构体的释放
- linux中文件描述符fd和struct file结构体的释放
- linux中文件描述符fd和struct file结构体的释放
- Linux2.6 struct file_operations
- Linux "零拷贝" sendfile函数中文说明及实际操作分析
- 文件结构体struct file(Linux 2.6.23内核)
- 解决error C2011: 'fd_set' : 'struct' type redefinition问题
- linux 笔记 关于struct file 结构下 private_data 数据结构的思考
- 同时使用afxsock.h及winsock2.h的方法 error C2011: 'fd_set' : 'struct' type redefinition的问题
- Joomla!在Linux平台提示"No input file specified."
- IBM UNIX & LINUX -AIX 5L 系统管理技术 学习笔记1 -网络文件系统 NFS network file system
- VS2010包含windows.h时winsock2.h出现"fd_set":struct类型重定义
- error C2011: 'fd_set' : 'struct' type redefinition 。。。
- 交叉调试时arm-linux-gdb提示:No symbol table is loaded. Use the "file" command.
- 【转载】文件结构体struct file(Linux 2.6.23内核)
- 文件结构体struct file(Linux 2.6.23内核)
- arm-none-linux-gnueabi-gcc: VERSION": No such file or directory
- fopen 与 open可以转换 即 FILE-->FD