0

古い INI ファイルを長年使用してきた経験から、最近 XML ファイルの使用を開始しました。

私の同僚が、System.Xml.XmlDocument.Save を使用する CodeProject サンプル コードを見つけました。2 つのプログラムが同時に同じファイルに書き込もうとすると、例外が発生します。

System.IO.IOException: 別のプロセスで使用されているため、プロセスはファイル 'C:\Test.xml' にアクセスできません。

これは後から考えると明らかですが、Win32 API を介した INI ファイルへのアクセスにはこの制限がないため、予期していませんでした。XmlDocument.Save メソッドよりも高いレベルで機能する Win32 呼び出しによって何らかの調停が行われると思います。

.Net ライブラリのどこかに、Win32 関数と同様に機能する高レベルの XML ルーチンがあることを願っていますが、どこから探し始めればよいかわかりません。

それとも、複数のプログラムが同じファイルに書き込めるようにファイル アクセス許可を設定できますか?

時間は短く (ほぼすべての SW プロジェクトと同様)、解決策がすぐに見つからない場合は、我慢して INI ファイルに戻る必要があります。

4

6 に答える 6

5

これはうまくいきません。2 つのプロセスが同じファイルに書き込むことができたとしても、ファイルが破損するだけです。複数のプログラムを同時に書き込む必要がある場合は、代わりにデータベースを使用します。

または、1 つの XML ファイルを複数のファイルに分割できますか? 各プロセスが独自のファイルに書き込み、「読み取り」メソッド中にすべてのファイルを結合します。

于 2010-06-10T16:49:38.327 に答える
2

これらのプログラムが同じセッションで実行されている場合は、ファイルへの書き込みを処理する別のクラスを作成し、シングルトン (または多数のファイル名にマップするマルチトン) 設計パターンを使用して、このクラスのインスタンスが 1 つだけであることを保証できます。これにより、I/O 例外がなくなります。「ファイルへの書き込み」要求ごとに、この新しいクラスのバッファーを必ずフラッシュしてください。

注意: これにより、プログラムにグローバルな状態が導入されます。この理由から、シングルトンはアンチパターンであると考えられています。

さらに、XML ファイルはツリー構造を形成するため、これはうまく機能しない場合があります。つまり、ファイルに書き込み変更を加える前に、ファイル全体を再読み込みする必要があります (末尾に単純に「追加」することはできません)。ファイルを削除しないと、ファイルが破損します)。

XMLを使おうとしている理由を検討する必要があると思います。「ダムデータベース」のように使用しようとしている場合は、SQLite のような実際の「軽量」データベースへの移行を検討する必要があります。ファイルの末尾に繰り返し追加する必要がある場合は、.ini のようなフラット ファイルを使用しても問題はありません。

于 2010-06-10T17:12:36.130 に答える
1

私の知る限り、複数のプロセスがファイルに書き込むのは難しいです - 同時実行を処理する方法は?

ただし、一方のファイルを読み取り、もう一方のファイルを書き込みたい場合は、それで機能します (リーダーが少し古いファイルを読み取る可能性を気にしない限り)。その場合はXmlDocument.Load、読み取り専用ファイル アクセスで初期化された FileStream を渡す関数を使用します。

System.Xml 名前空間の多く (ほとんど?) にもスレッド セーフなオーバーロードがありますが、アプリケーションのすべてのインスタンスを 1 つのプロセスにまとめることができない限り、クロス プロセス ファイル アクセスが必要なようです。

したがって、もし私があなたなら、マルチプロセス アクセスをサポートする、より豊富なデータ ストアを検討します。ある種のデータベースが最も明白な答えです。

編集:コメントごとに修正。

于 2010-06-10T16:56:05.020 に答える
1

ファイルを分割する代わりに、データベースを使用することもできます。XML データベースがあり、ウィキペディアにはそれらのいくつかがリストされています。

しかし、私はそれらのいずれかを保証することはできません.

于 2010-06-10T16:58:55.280 に答える
1

最初の問題は、書き込み時にファイルを閉じてからもう一度開いてみることで解決できます。次に、それを開いたままにして、読み取り、変更をマージしてから、もう一度書き出す必要があります。(変更をマージする必要があります。そうしないと、アプリケーションがファイルを読み取ってから再度書き出すまでの間に行われた変更が上書きされます)。

INI ファイルは 2 回置き換えられました。1 回目はレジストリによるもの、2 回目はConfigurationManagerによるものです。ConfigurationManager を試してみることをお勧めします。ファイルが変更された場合、またはファイルに書き込めない場合、Configuration.Saveは例外をスローするようです。その場合、例外をキャッチして数回再試行します。

于 2010-06-10T16:58:59.460 に答える
0

XML ファイルは、INI ファイルよりもその構造 (スキーマ/DTD など) に敏感です。また、Win32 の INI メソッドは、ファイル アクセスの複雑さを隠します。理論的には、ファイル レベルではなくタグ レベルでロックするある種のスレッド セーフなライターを考え出すことができますが、それはすぐに使用できる機能ではありません。

于 2010-06-10T17:01:52.603 に答える