在C中,当我们打开文件时会发生什么?据我所知,当我们打开文件时,文件的内容没有加载到内存中。它只是设置文件描述符?那么这个文件描述符是什么呢?如果文件的内容没有加载到内存中那么文件是如何打开的?
答案 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)
这个问题与编程语言并不完全相关。虽然库确实对打开文件时会发生什么影响(例如,使用open
或fopen
),但主要行为来自操作系统。
Linux,我认为其他操作系统在大多数情况下都会执行预读。这意味着即使在为文件调用read
之前,实际上也从物理存储中读取了文件。这是作为优化完成的,减少了用户实际读取文件时的读取时间。程序员可以使用打开函数的特定标志来部分控制此行为。例如,Win32 API CreateFile
可以指定FILE_FLAG_RANDOM_ACCESS
或FILE_FLAG_SEQUENTIAL_SCAN
来指定随机访问(在这种情况下文件未提前读取)或顺序访问(在这种情况下操作系统将执行分别是非常积极的预读)。其他OS API可能会提供更多或更少的控制权。
对于使用文件描述符的open
,read
,write
的基本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;