【发布时间】:2020-01-09 14:23:58
【问题描述】:
我有一个线程监视目录中的文件添加(如果存在则使用inotify,否则轮询),并在监视目录中创建的新文件时通知侦听器。侦听器具有基于创建文件大小的条件逻辑,它使用int stat(const char *pathname, struct stat *statbuf) 确定。
在一个单独的线程中,我使用 std::ofstream 创建了一个非零长度文件;文件创建的简化示例是:
std::ofstream ofs( "/path/to/file", std::ofstream::out );
ofs << "abc";
ofs.close()
运行时行为是调用stat() 的侦听器有时将文件视为0 长度。
这是完全合理的,因为文件创建和内容添加是单独的操作。
问题:有没有办法使用C 函数或C++03 的stl 原子地创建非零长度文件?
注意:出于这个问题的目的,我对同步原语(如互斥锁或信号量)不感兴趣,以在文件打开、添加内容、关闭文件的整个过程中同步两个线程。
【问题讨论】:
-
为什么不直接将现有文件复制到目录中?
-
您可以在 不同的 目录中创建文件。关闭文件后,您可以将文件移动(重命名)到正确的目录。那么
inotify会检测到文件吗? -
@NathanOliver - 我想知道:非零文件的副本是否可以作为非零文件的“原子”外观,或者副本本身是否经历(1 ) 0 长度文件创建,(2) 内容添加,(3) 文件关闭。
-
据我了解,唯一不平凡的 POSIX 操作至少在某种程度上是原子的,至少在某种程度上是可移植的,它是不跨越文件系统/设备边界的
rename。但是我的 POSIX-fu 很弱。 -
我建议当您在单独的线程(例如 test.txt)中创建新文件时,将其命名为 text.txt.part 之类的名称,然后在您的第一个线程中让它忽略扩展名为 .part 的文件.然后,当您准备好时,将文件重命名为正确的名称。从长远来看,这实际上可能对您有所帮助,因为其他进程通常使用 .part 来表示文件不完整(例如,当您下载文件时,或者有人也在您上传文件时)。但是我不确定重命名它是否会注册为新文件。
标签: c++ c file filesystems