假设你有一个非常大的二进制文件。您经常更新它,但是,当您这样做时,您只需覆盖它的一小部分而不改变文件的大小。要实现此目的,请使用fopen(“rb +”),搜索位置并执行写入。
操作系统如何实际实现此功能?由于更新模式允许您写入文件的末尾并因此增加其大小,因此我假设有时必须重新创建文件并将其移动到其他位置。但是,在上述情况下,每次重新创建文件似乎都会出现性能问题和/或破坏闪存驱动器。
fopen的手册页根本没有进入这个...
答案 0 :(得分:1)
fopen
手册页没有提到这一点的原因是因为文件的实际创建和存储是依赖于文件系统的实现细节。实际上,fopen
可能根本不在物理文件上运行(例如fopen("/dev/tty", "w")
)。
但是,通常文件系统会将文件存储为磁盘块的集合。每个块都是一个连续的块(从512字节到32KB以上),但文件中的块可能不是物理上连续的(当发生这种情况时,文件被“分段”)。所以,如果你写过文件的末尾并且文件系统需要在文件中添加一个新块,它就会找到磁盘上的下一个空闲块并开始写入。
然而,SSD和其他闪存存储要求在再次写入之前完全擦除块(最大可达128KB)。因此,对磁盘块的任何更新都需要编写一个新块。 (这发生在每次写入最终都在磁盘上,而不仅仅是写在文件末尾的那些。)答案 1 :(得分:1)
每个文件系统如何存储其文件取决于文件系统,而不是立即实现fopen
。看到一个必须重新定位整个文件以扩展它的系统会很奇怪。文件通常存储在“慢速”存储中,这意味着文件系统的整个设计专用于在“慢速存储”条件下尽可能高效地扩展文件等操作。
将文件存储在文件系统中的一种流行的,最直接的方法(想想FAT)是将文件组织为一些预定大小的磁盘“块”序列。将新数据写入文件末尾时,会将其写入最后一个块,直到它变满为止。之后,在存储器中的某处分配新块并将其附加到文件末尾。等等。显然,这可能容易导致多个文件以交错方式存储它们的块,即物理上这些文件是非连续存储的。这会对输入/输出性能产生负面影响,但这被认为是支付相当好的文件扩展性能的可接受价格。
换句话说,文件不会被重新创建或重新定位。它只是在最后扩展。