2008-08-26 17 views
4

ログファイルを解析して特定のデータをサーバーに送信するアプリケーションを開発する必要があります。 LinuxとWindowsの両方で実行する必要があります。C++:非排他モードでファイルを開く

ログローリングシステム(名前に.1を追加すると、同じ名前の新しいものを作成する)をテストするときに問題が発生します。 Windowsで(まだLinux上でテストしていない)私は "入力モード"(ios :: in)で開いていても、std :: ifstream()(排他的アクセス?)で開いたファイルの名前を変更できません。 。

ファイルを非排他的に開くためのクロスプラットフォームの方法はありますか?

答えて

3

非排他的な方法でファイルを開くための方法はあり、

はい、、。

はクロスプラットフォームですか?

いいえ、プラットフォーム固有のコードが必要です。

DOSアプリケーションはシングルタスクであるため、何もファイルを削除できない、つまりfclose()とfopen()を何も起こさずに削除できると仮定します; Win16 preservedこの仮定は、DOSアプリケーションの移植を容易にするため、Win32はWin16アプリケーションの移植を容易にするためにこの前提を保持していましたが、ひどいです)、Windowsはファイルを排他的に開くことをデフォルトにしています。

オープンソースファイルの削除/名前変更をサポートしています(ただし、メモリマップファイルは削除できないと考えていますが、* nixの制限ではないと思いますが)意味論はしません。

C++には、このような概念はありません。 C++の動作環境はDOSの動作環境とほぼ同じです。他のアプリケーションは同時に動作しないため、ファイル共有を制御する必要はありません。

1

これは排他モードを必要とする読み取り操作ではなく、名前を変更することです。これは、ファイルを新しい場所に移動することと本質的に同じですからです。

わかりませんが、これはできないと思います。代わりにファイルをコピーし、後で読み込まれなくなった古いファイルを削除/置き換えてください。

1

Win32ファイルシステムのセマンティクスでは、名前を変更するときに、名前を変更したファイルを(任意のモードで)開く必要がありません。ファイルを閉じて名前を変更し、新しいログファイルを作成する必要があります。

ファイルシステムのセマンティクスを使用すると、ファイル名がiノードのポインタにすぎないため、開いているファイルの名前を変更できます。

1

私はそれがWindows APIのCreateFileで行うことができます知っているファイルからのみ読んでいる場合。 FILE_SHARE_DELETE |を指定するだけです。 FILE_SHARE_READ | FILE_SHARE_WRITEをdwShareModeの入力として使用します。

残念ながら、これはクロスプラットフォームではありません。しかし、Linuxには似たようなものがあるかもしれません。

See msdn for more info on CreateFile

編集:Greg Hewgillのコメントについての簡単なメモ。私はちょうどFILE_SHARE *のものでテストしました(あまりにも100%確実です)。また、読み取り専用でFILE_SHARE *パラメータを指定すると、ファイルを削除して名前を変更することもできます。 CreateFileに様々なFILE_SHARE_Xxxxフラグを渡すのWin32を使用して

0

ファイルを開いたままにしないでください。たとえば、アプリがクラッシュした場合、これは奇妙なものにつながります。私はどうだろう何 :

  1. 抽象画(読み込み/書き込み/新しいファイルにロールオーバー)一つのクラスに、そしてあなたがそのクラスの新しいものにロールオーバーするときに、ファイルのクローズをアレンジ。 (これは一番きれいな方法で、既にロールオーバーコードを持っているので、すでに途中にいるからです)
  2. 複数の読み書きアクセスポイントが必要な場合は、fstreamのすべての機能が必要で、私が考えることができる唯一のクロスプラットフォームのソリューションは、あなたがそれを必要としないときに常にファイルを閉じて、ロールオーバーコードが必要なときにファイルへの排他的アクセスを取得しようとすることですあきらめる前にロールオーバーする。
関連する問題