什么是在C中打开文件?

时间:2010-12-27 06:39:40

标签: c file

在C中,当我们打开文件时会发生什么?据我所知,当我们打开文件时,文件的内容没有加载到内存中。它只是设置文件描述符?那么这个文件描述符是什么呢?如果文件的内容没有加载到内存中那么文件是如何打开的?

7 个答案:

答案 0 :(得分:6)

通常情况下,如果您使用fopen或(在POSIX系统上)open打开文件,该函数如果成功,将“打开文件” - 它只是为您提供一个值(a FILE *int)将在以后调用read函数时使用。

在幕后,操作系统可能会读取部分或全部文件,但可能不会。您必须调用某个函数来请求才能读取数据,如果在您致电fread / fgets / read /等时尚未执行此操作,那么...它将在那时。

“文件描述符”通常是指POSIX系统中open返回的整数。它用于标识打开的文件。如果您在某处获得值3,则操作系统会跟踪3引用/home/user/dir/file.txt或其他任何内容。这是一个很小的值,用于向OS 指示要读取的文件。当您致电open并打开说foo.txt时,操作系统会说,“好吧,文件打开,从此处调用3”。

答案 1 :(得分:4)

这个问题与编程语言并不完全相关。虽然库确实对打开文件时会发生什么影响(例如,使用openfopen),但主要行为来自操作系统。

Linux,我认为其他操作系统在大多数情况下都会执行预读。这意味着即使在为文件调用read之前,实际上也从物理存储中读取了文件。这是作为优化完成的,减少了用户实际读取文件时的读取时间。程序员可以使用打开函数的特定标志来部分控制此行为。例如,Win32 API CreateFile可以指定FILE_FLAG_RANDOM_ACCESSFILE_FLAG_SEQUENTIAL_SCAN来指定随机访问(在这种情况下文件未提前读取)或顺序访问(在这种情况下操作系统将执行分别是非常积极的预读)。其他OS API可能会提供更多或更少的控制权。

对于使用文件描述符的openreadwrite的基本ANSI C API,文件描述符是一个简单的整数,传递到操作系统并表示文件。在操作系统本身中,这通常被转换为包含文件所需的所有信息的一些结构(名称,路径,查找偏移,大小,读取和写入缓冲区等)。操作系统将打开文件 - 意味着找到与您在inode方法中给出的路径相关的特定文件系统条目(Linux下的open),创建文件结构并返回ID给用户 - 文件描述符。从那时起,操作系统可以自由地读取它看起来合适的任何数据,即使用户没有请求(读取的次数通常超过了请求,至少在文件系统本机大小下工作)。

答案 2 :(得分:2)

C没有文件I / O的原语,这完全取决于操作系统 以及你正在使用的库。

答案 3 :(得分:1)

文件描述符只是摘要。一切都在操作系统上完成。

答案 4 :(得分:1)

如果程序使用fopen(),则缓冲程序包将使用特定于实现的系统调用来获取文件描述符,并将其存储在FILE结构中。

系统调用(至少在Unix,Linux和Mac上)将查找(通常)基于磁盘的文件系统以查找文件。它在内核内存中创建数据结构,用于收集读取或写入文件所需的信息。

它还为每个进程创建一个表,该表链接到访问该文件所需的其他内核数据结构。该表的索引是(通常)较小的数字。这是从系统调用返回给用户进程的文件描述符,然后存储在FILE结构中。

答案 5 :(得分:0)

如前所述,它是操作系统功能。

但对于C文件I / O,您可能需要fopen函数的信息。

如果您要检查该功能的说明,请说:

  

说明

     

打开一个流。

     

fopen打开名为的文件   filename并将流与之关联   它。 fopen返回一个要使用的指针   在后续中识别流   操作

因此,成功完成时fopen只返回指向新打开的流的指针。如果出现任何错误,它将返回NULL。

答案 6 :(得分:0)

当您打开文件时,文件指针将获取该文件的基址(起始地址)。然后使用不同的函数处理该文件。 编辑: 感谢Chris,这里的结构名为FILE

typedef struct  {
       int             level;      /* fill/empty level of buffer */
       unsigned        flags;      /* File status flags          */
       char            fd;         /* File descriptor            */
       unsigned char   hold;       /* Ungetc char if no buffer   */
       int             bsize;      /* Buffer size                */
       unsigned char   *buffer;    /* Data transfer buffer       */
       unsigned char   *curp;      /* Current active pointer     */
       unsigned        istemp;     /* Temporary file indicator   */
       short           token;      /* Used for validity checking */
}      FILE;