我在普通文件描述符上调用 write(fd, buf, N) 。
调用之前的文件指针不在文件的开头或结尾,而是在文件的中间某处。
然后,呼叫会因断电而中断(或任务被终止)。能否保证文件中 N 字节前后的数据会发生什么情况?是否保证它们保持不变?
答案1
我看到两个不同的问题:
- 如果写入过程中断电会发生什么?
无法保证断电时会发生什么——您甚至可能会丢失整个文件系统。
但也有一些典型的行为。如果文件系统正在为写入区域分配新块,则在断电时可能无法写入新块的文件系统元数据,并且文件可能会丢失或截断。但是,如果您正在写入文件的中间并且块已经分配,那么应该没问题,但不能保证有多少写入写入了磁盘。可能是一些、全部或没有。
正如评论中所指出的,对于 CoW 或网络文件系统等特殊文件系统,行为可能有所不同。日志文件系统尝试使此类问题的恢复更加优雅。此外,RAID 阵列通常具有缓冲硬件,可以在断电时保存不完整的写入。
- 如果进程在写入过程中被终止会发生什么?
这里有两种情况。如果您指的是 write(2) 系统调用,则这主要是原子性的,它可能在进程实际终止之前完成,或者可能根本不启动。在某些情况下,写入可能是可中断的,但通常不是。
如果您的意思是使用 stdio 缓冲的库调用(例如 fwrite(3)),那么进程可能有未写入的缓冲数据,当进程被终止时这些数据不会被写入。通常,stdio 以块的形式将数据缓冲到磁盘;当缓冲区有完整的块时,它调用 write(2)。