文件进程linux系统编程之文件与I/O(五):打开文件的内核结构file和重定向
2013-05-14 20:51
363 查看
最近研究文件进程,稍微总结一下,以后继续补充:
一、打开文件内核数据结构
1、一个进程打开两个文件
![](http://img.blog.csdn.net/20130514162407251)
文件状态标记:读、写、追加、同步、非阻塞等
2、一个进程两次打开同一文件
![](http://img.blog.csdn.net/20130514162539532)
3、两个进程打开同一文件
![](http://img.blog.csdn.net/20130514162658404)
示例程序:
C++ Code
每日一道理
美丽是平凡的,平凡得让你感觉不到她的存在;美丽是平淡的,平淡得只剩下温馨的回忆;美丽又是平静的,平静得只有你费尽心思才能激起她的涟漪。
假设test.txt文件的内容是 ABCDEhello
测试如下:
simba@ubuntu:~/Documents/code/linux_programming/APUE/File_IO$ ./file_share
buf1=ABCDE
buf2=ABCDE
buf1=AAAAA
test.txt文件内容变成 ABCDEAAAAA
分析:由上图分析可知,一个进程两次打开同一文件,文件表是不同享的,即各有自己的文件偏移量和打开文件标记,所以两次read不同的fd都是从头开始读取,但V节点表是同享的,在fd2写入(同个文件表的read和write是同享偏移的)更改了inode指向的硬盘数据块,再次read fd1失掉的也是更改后的值。
二、I/O重定向
![](http://img.blog.csdn.net/20130514164410314)
![](http://img.blog.csdn.net/20130514164439823)
当我们执行了dup(3)之后,系统选择一个闲暇的文件描述符即4,这样就有两个文件描述符指向同个文件表,所以引用计数为2。利用dup等函数可以停止重定向的步调是先close输入输出文件描述符,然后执行dup(fd), 这样输入输出文件描述符也指向fd指向的文件,这样就实现了重定向。此外dup2, fcntl 函数也可以实现,其实不使用这些函数,而直接close(0/1/2)完再open也可以实现。
示例程序如下:
C++ Code
文章结束给大家分享下程序员的一些笑话语录:
PC软件体积大,是因为一个PC软件功能往往较多,能够满足你一个方面的需求,而一个iphone软件往往没几行代码,干一件很小的事情,自然需要的软件就多。就像吃西瓜和吃瓜子的来比数目,单位不同啊。
一、打开文件内核数据结构
1、一个进程打开两个文件
文件状态标记:读、写、追加、同步、非阻塞等
2、一个进程两次打开同一文件
3、两个进程打开同一文件
示例程序:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /************************************************************************* > File Name: file_share.c > Author: Simba > Mail: dameng34@163.com > Created Time: Sat 23 Feb 2013 02:34:02 PM CST ************************************************************************/ #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #include<fcntl.h> #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while( 0) int main( int argc, char *argv[]) { int fd1, fd2; char buf1[ 1024] = { 0}; char buf2[ 1024] = { 0}; /* 进程控制块PCB * struct task { * ... * struct files_struct *files; * } * 同一个进程两次打开同一个文件,一个进程具有的一个文件描述符表其中一个fd索引对应的指针指向一个 * 文件表(包括文件状态(读写追加同步非阻塞等),当前文件偏移量, * 文件引用次数(当有两个fd指向同个文件表时引用计数为2,见dup,也可用于重定向), * 文件操纵指针, V节点指针等)不同享, * V节点表(包括V节点信息(struct stat), i节点信息等)同享 */ /* 两个进程打开同一个文件的情况与上类同*/ fd1 = open( "test.txt", O_RDONLY); if (fd1 == - 1) ERR_EXIT( "open error"); read(fd1, buf1, 5); printf( "buf1=%s\n", buf1); fd2 = open( "test.txt", O_RDWR); if (fd2 == - 1) ERR_EXIT( "open error"); read(fd2, buf2, 5); printf( "buf2=%s\n", buf2); write(fd2, "AAAAA", 5); memset(buf1, 0, sizeof(buf1)); read(fd1, buf1, 5); printf( "buf1=%s\n", buf1); close(fd1); close(fd2); return 0; } |
美丽是平凡的,平凡得让你感觉不到她的存在;美丽是平淡的,平淡得只剩下温馨的回忆;美丽又是平静的,平静得只有你费尽心思才能激起她的涟漪。
假设test.txt文件的内容是 ABCDEhello
测试如下:
simba@ubuntu:~/Documents/code/linux_programming/APUE/File_IO$ ./file_share
buf1=ABCDE
buf2=ABCDE
buf1=AAAAA
test.txt文件内容变成 ABCDEAAAAA
分析:由上图分析可知,一个进程两次打开同一文件,文件表是不同享的,即各有自己的文件偏移量和打开文件标记,所以两次read不同的fd都是从头开始读取,但V节点表是同享的,在fd2写入(同个文件表的read和write是同享偏移的)更改了inode指向的硬盘数据块,再次read fd1失掉的也是更改后的值。
二、I/O重定向
当我们执行了dup(3)之后,系统选择一个闲暇的文件描述符即4,这样就有两个文件描述符指向同个文件表,所以引用计数为2。利用dup等函数可以停止重定向的步调是先close输入输出文件描述符,然后执行dup(fd), 这样输入输出文件描述符也指向fd指向的文件,这样就实现了重定向。此外dup2, fcntl 函数也可以实现,其实不使用这些函数,而直接close(0/1/2)完再open也可以实现。
示例程序如下:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /************************************************************************* > File Name: file_dup.c > Author: Simba > Mail: dameng34@163.com > Created Time: Sat 23 Feb 2013 02:34:02 PM CST ************************************************************************/ #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #include<fcntl.h> #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while( 0) /* dup dup2 fcntl */ int main( int argc, char *argv[]) { int fd; fd = open( "test2.txt", O_WRONLY); if (fd == - 1) ERR_EXIT( "open error"); /* close(1); dup(fd); */ // dup2(fd, 1); close( 1); if (fcntl(fd, F_DUPFD, 0) < 0) //从0开始搜索可用的fd ERR_EXIT( "fcntl error"); printf( "hello\n"); // 输出重定向到test2.txt return 0; } |
PC软件体积大,是因为一个PC软件功能往往较多,能够满足你一个方面的需求,而一个iphone软件往往没几行代码,干一件很小的事情,自然需要的软件就多。就像吃西瓜和吃瓜子的来比数目,单位不同啊。
相关文章推荐
- linux系统编程之文件与I/O(五):文件的内核结构file和dup实现重定向
- linux系统编程之文件与I/O(五):文件的内核结构file和dup实现重定向
- 文件的内核结构file和dup实现重定向
- FILE,文件句柄,打开文件列表和内核文件对象的关系
- Linux 文件系统结构(Filesystem Hierarchy Standard)
- System.IO.FileSystemWatcher与文件的打开状态
- File对文件的操作,创建、复制、删除、移动和打开文件的静态方法
- fatal error C1083: 无法打开包括文件:“qedit.h”: No such file or directory
- fatal error C1083: 无法打开包括文件:“new.h”: No such file or directory
- openfiledialog 打开txt文件 textbox 中文乱码
- Qt之opengl:错误: 无法打开包括文件:“gl/glut.h”: No such file or directory
- 【解决】 无法打开包括文件:“windows.h”: No such file or directory
- vs2008出现fatal error C1083: 无法打开包括文件:“afxcontrolbars.h”: No such file or directory
- VS2015 QT工程中无法打开包括文件: “QDialog”: No such file or directory问题
- Linux修改进程能打开最大文件数(Could not set limit for ‘nofile’: Operation not permitted)
- qt 无法打开包括文件:“QApplication”: No such file or directory
- \avformat.h(40) : fatal error C1083: 无法打开包括文件:“libavcodec/avcodec.h”: No such file or directory
- vs2013之OpenGL错误: 无法打开包括文件:“GL/glut.h”: No such file or directory和OpenGL程序无法启动此应用程序,因计算机中丢失glut32.dll
- DayDayUp_bug解决_vmware安装无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件
- 文件I/O之-打开文件在内核中的表示