我正在尝试用C ++编写一个类,它提供了一种原子附加到文件的方法,即使是在写入中断电源的情况下也是如此。
首先,我将当前文件位置(从文件开头的64位偏移量,以字节为单位)写入单独的日志文件。然后,我将请求的数据写入日期文件的末尾。最后,我在日志文件上调用ftruncate()(将截断的大小设置为0)。
主要思想是,如果要求此类打开具有非空日志文件的文件,那么您知道写入被中断,您可以从日志文件读取最后一次写入的位置,并且fseek到那个地方。你丢失了最后一次部分写入,但文件不应该被破坏。
不幸的是,似乎ftruncate()是异步的。实际上,即使我在ftruncate之后调用fflush()和fsync(),我也会看到日志在执行大量写操作时增长到数百个字节。它最终总是在0,但我希望它始终在0或8大小。
是否可以使ftruncate完全同步?或者有更好的方法来使用期刊吗?
答案 0 :(得分:5)
ftruncate()
不会更改文件描述符在文件中的写入偏移量。如果您打开文件并在调用ftruncate()
后写下一个长度,那么正在发生的是文件的偏移量仍在增加。写入时,它会将文件的长度重置为偏移量,然后将字节写入其中。
您可能想要做的是在致电lseek(fd, 0, SEEK_SET)
后致电ftruncate()
,以便下一次写入文件将发生在文件的开头。