C/C++:有没有办法自动创建一个非零长度的文件?

C/C++: is there a way to create a nonzero-length file atomically?

我有一个线程监视文件添加的目录(如果存在则使用 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++03stl 自动创建非零长度文件?

注意:出于这个问题的目的,我对同步原语不感兴趣,比如互斥锁或信号量,围绕文件打开、添加内容、关闭文件的整个过程同步两个线程。

基础 C 语言没有这样的概念,我认为 C++ 也没有。如果您在谈论这些类型的事情,您必须假设 POSIX 或其他一些操作系统级行为规范。

在POSIX下,进行这种操作的方法是创建一个临时名称的文件,然后rename只有在您完成写入后才可以。如果它们都在同一台设备上,您可以在不同的目录中执行此操作;如果它们在不同的设备上,是否有效是实现定义的。最便携的方法是在同一目录中执行此操作,这意味着您的 inotify(Linux-specific,BTW)侦听器应忽略与其正在查找的命名模式不匹配的文件或忽略文件您选择作为约定的特定临时命名空间。

Is there a way to atomically create a nonzero-length file using either C functions or C++03's stl?

最好的方法是在同一文件系统的其他地方创建文件,然后 std::rename 将文件放入目标文件。

除了 post 条件(文件以新名称或旧名称存在)之外,该标准并没有真正给出明确的保证。与可观察的中间状态无关。实际上,您受制于文件系统。但是,如果有一些标准操作可以实现您想要的,那么就是这样。 POSIX 标准确实要求 rename 是原子的。