2016-02-29 98 views
9

我需要开发一个执行这个显而易见的小任务的C++例程:只有在文件不存在时才创建文件,否则什么都不做/引发错误。创建一个避免竞争条件的新文件

由于我需要避免竞争条件,我想使用“请求宽恕不允许”原则(即尝试预期的操作并检查是否成功,而不是事先检查先决条件),根据我的知识,是用于此目的的唯一稳健和便携式方法。[Wikipedia article][an example with getline]

不过,我无法找到一种方法来实施它在我的情况。我能想到的最好方法是在app模式下打开fstream模式(或fopen使用"a"),使用tellp(C++)或ftell(C)检查输出位置,如果此位置不为零则中止。这有两个缺点,即如果文件存在,它会被锁定(虽然时间很短),并且其修改日期被修改。

我检查的ios_base::openmodefstream其他可能的组合,以及对fopenmode字符串但没有发现这适合我的需求选择。在C和C++标准库以及Boost文件系统中进一步搜索证明是不成熟的。

有人可以指出一种方法来执行我的任务以强大的方式(没有附带影响,没有竞争条件),而不依赖于操作系统特定的功能? 我的具体问题是在Windows中,但便携式解决方案将是首选。

编辑:BitWhistler的答案完全解决了C程序的问题。尽管如此,我仍然惊讶于没有C++惯用的解决方案似乎存在。任何一个使用openO_EXCL属性是由Andrew Henle提出的,但是它是OS特有的(在Windows中该属性似乎被称为_O_EXCL并带有下划线[MSDN]),或者分别编译C11文件并将其与C++代码链接。此外,除非使用非标准扩展名(例如GCC的__gnu_cxx::stdio_filebuf),所获得的文件描述符不能转换为流。我希望将来的C++版本将实现文件流的"x"子属性以及可能的相应ios::修饰符。

+0

你想避免多个线程或几道工序间的竞争状态? – user2807083

+3

什么是您的操作系统? POSIX提供['open(filename,O_CREAT | O_EXCL ...)'](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html)来执行你想要做的事情。 –

+1

Win32 API允许这样做。我确实知道这一点。 –

回答

3

新的C标准(C2011,它不是C++的一部分)添加了一个新的标准子指定符(“x”),可以附加到任何“w”说明符(形成“wx”,“wbx” “w + x”或“w + bx”/“wb + x”)。如果文件存在,则该子指令强制该功能失败,而不是覆盖它。

来源:http://www.cplusplus.com/reference/cstdio/fopen/