(一)
首先,对于内核来讲,它是利用“文件描述符”来访问文件的。文件描述符一般是一个非负的整数。当我们用open打开已有的文件或者用creat创建新的文件时,都会返回一个文件描述符。有了文件描述符之后,我们就可以利用该文件描述进行文件的读写,即read、write系统调用都需要文件描述符fd(file descriptor)作为其参数。从以上描述可以看出,当我们想要用read、write等系统调用对文件进行读写等操作之前,必须用open或creat系统调用得到文件的描述符。
一般Unix系统中shell使用文件描述符0与进程的标注输入相关联,文件描述符1与进程的输出相关联,文件描述符2与标注错误相关联。在应用程序中,一般用0、1、2代替常量STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。这些代替都定义在</usr/include/unistd.h>头文件中:
/*standard file descriptors*/
#define STDIN_FILENO 0 /*input*/
#define STDOUT_FILENO 1 /*output*/
#define STDERR_FILENO 2 /*error output*/
示例程序如下:
/*demo.c*/ #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(void) { int fd; /*打开文件test.c,由于不存在,所以打开失败,返回-1*/ fd = open("test.c", O_RDONLY); printf("fd = %d.\n",fd); /*创建文件,因为描述符0、1、2属于默认,所以创建的该描述符为3*/ fd = creat("test.c", O_RDWR); printf("fd = %d.\n",fd); return 0; }
编译执行: gcc demo.c ./a.out 结果显示: fd = -1. fd = 3.
每个进程在Linux内核中都有一个task_struct结构体来维护进程的相关信息,称为进程描述符。进程描述符task_struct中有个指针成员(struct files_styruct *files)指向files_struct结构体,称为文件描述符表,其中的每个表项包含一个指向已打开的文件的指针。
用户不能直接访问内核中的文件描述符表,而只能使用文件描述符表的索引,即文件描述符。
(三)
文件描述符、文件指针、文件路径三者有联系也有区别,开始学习时很难理清三者的关系。
首先,文件描述符fd一般是在Unix系统或类Unix系统中的概念,它其实是一个整数,用它可以来获取文件描述符表中的某个已打开文件。
文件指针FILE是C库中的概念,它不单单在Linux系统中,在windows中也会出现,文件指针指向进程中用户区中一个被称为FILE结构的数据结构,该FILE结构包括一个缓冲区和一个文件描述符。FILE中包含fd信息,还包含IO缓冲,所以FILE比fd更适合跨平台。它们之间可以利用fdopen函数和fileno函数互相转化。
FILE *fdopen(int fd, const char *mode);
int fileno(FILE *stream);
文件路径就是文件所在路径,通常,我们就是通过文件路径得到具体文件,从而得到文件描述符、文件指针的。
Linux环境编程之文件I/O(一):文件描述符,布布扣,bubuko.com
原文地址:http://blog.csdn.net/to_be_it_1/article/details/25475573