FILE
结构分配空间,在此
FILE
结构内部将有一个i/0的缓冲区。但是后来,我发现
write
系统调用实际上将数据写入内核缓冲区。那么,这两个缓冲区有什么区别?您必须理解两件事:
fwrite()
是标准库在FILE
write()
是系统调用。我敢打赌
fwrite()
在内部使用write()
。没有什么可以阻止提供用户空间io buffering,直到它准备好将数据传递到fwrite()
syscall.write()
syscall在依次直接到内核,说:“嘿,内核,我在这里有这个用户空间缓冲区。您会为我写这封信吗?”。 这取决于内核下一步要做什么:它将直接转到存储以编写数据,或者很可能将数据复制到内核缓冲区,直到它决定该修改存储数据的时候了。
回到您的问题。进行任何类型的缓冲是为了累积数据以推迟转向更昂贵的操作:标准库可能会考虑在每个昂贵的每个byte上调用syscall,内核认为在每个syscall上都会在每个syscall上使用硬盘,等等。您可能想阅读此内容以查看缓冲多远。 结构持有有关打开文件(模式,流位置等)的
meta
数据。它是C标准I/O接口的一部分。 分配的缓冲区作为
write()
的一部分仅获取有限量的数据(例如,当流缓冲时)。它是在len
上划分的。您甚至可以提供自己的用户空间STDIO缓冲区。每当刷新流或关闭相关的文件描述符时,内核缓冲区都会收到file内容。
缓冲区,另一个是
FILE
缓冲区。因此,当您进行I/O时,基本上发生的事情是将用户空间的缓冲区复制到内核空间中的缓冲区。功能fclose()
执行此任务。
现在出现的问题是,当内核可以访问用户空间时,为什么我们需要两个缓冲区?原因是内核不想直接读取用户缓冲区,因为内核和用户空间都有不同的地址空间,因此用户空间中的有效地址可能不是内核中的有效地址。中内核如果访问了非valid地址,则系统将立即恐慌,因此该功能
setvbuf()
执行映射用户空间地址和内核空间地址的任务,并检查地址是否可访问。如果不是这样,它只是返回write()
(不良地址)。
文件结构包含有关打开的文件的信息。此定义文件结构成员。但是在内核级别,inode,buffercache
copy_to_user和
Copy_from_user..dtata通过缓冲缓存从用户空间读取/写入磁盘。