2016-02-29 17 views
9

これは明らかに簡単なタスクを実行するC++ルーチンを開発する必要があります。存在しない場合にのみファイルを作成し、それ以外の場合は何もしない/エラーを発生させます。競合状態を避けるために新しいファイルを作成する

競合状態を回避する必要があるので、私は「許諾ではない」という原則(つまり、事前に前提条件を確認するのではなく、意図した操作を試み、成功したかどうかを確認する) 、この目的のための唯一の堅牢で移植可能な方法です[Wikipedia article][an example with getline]

私の場合はまだ実装方法が見つかりませんでした。私が思いつくことができる最高の方法は、tellp(C++)またはftell(C)で出力位置を確認し、そのような位置がゼロでない場合は打ち切り、appモード(またはfopen ing "a")でfstreamを開きます。しかし、これには2つの欠点があります。つまり、ファイルが存在する場合、ファイルはロックされますが(短時間ですが)、その変更日が変更されます。

私は他の可能fstreamためios_base::openmodeの組み合わせだけでなく、fopenmode文字列をチェックしますが、私のニーズに合ったnoオプションを発見しました。 Boost Filesystemと同様に、CおよびC++の標準ライブラリでのさらなる検索は、実りありませんでした。

誰かが、OS特有の機能に依存することなく、堅牢な方法(付随効果なし、競合条件なし)で自分のタスクを実行する方法を指摘できますか? 私の具体的な問題はWindowsにありますが、ポータブルなソリューションが望ましいでしょう。

EDIT:BitWhistlerの答えは、Cプログラムの問題を完全に解決します。それでも、C++の慣用的な解決法は存在しないと私は驚きます。 Andrew Henleによって提案されているようにO_EXCL属性を持つopenを使用していますが、OS固有のものです(Windowsでは_O_EXCLと追加のアンダースコア[MSDN]が付いているようです)、またはC11ファイルを個別にコンパイルしてC++コード。さらに、取得されたファイル記述子は、標準以外の拡張子(GCCの__gnu_cxx::stdio_filebufなど)を除いてストリームに変換することはできません。私は将来のバージョンのC++でサブタイプ"x"を実装し、場合によっては対応するファイルストリームの修飾子ios::も実装することを願っています。

+0

は、あなたが複数のスレッドまたは複数のプロセス間の競合状態を回避したいですか? – user2807083

+3

あなたのOSは? POSIXはあなたがしたいことをするために['open(filename、O_CREAT | O_EXCL ...)'](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html)を提供しています。 –

+1

Win32 APIでこれが可能です。私は確かにこれを知っている。 –

答えて

3

新しいC標準(C2011、C++には含まれていません)は、 "wx"、 "wbx"などの任意の "w"指定子に追加できる新しい標準サブスペーサー( "x" "w + x"または "w + bx"/"wb + x")。このサブスペシファイヤーは、ファイルが上書きされるのではなく、ファイルが存在する場合にその関数を強制的に失敗させます。

ソース:http://www.cplusplus.com/reference/cstdio/fopen/

関連する問題