10

さまざまな形式(csv、tsv、ini、およびxml)のテキストファイルを処理する複数のWindowsプログラム(Windows 2000、XP、および7で実行)があります。ファイルIO中にこれらのファイルの内容を破損しないことが非常に重要です。すべてのファイルは、複数のプログラムから同時に安全にアクセスできる必要があり、システムのクラッシュに耐える必要があります。このSOの回答は、インプロセスデータベースの使用を示唆しているため、区切り文字のテキストファイル(csv、tsv)を処理でき、トランザクションをサポートするMicrosoft JetDatabaseEngineの使用を検討しています。。以前にJetを使用しましたが、Jetトランザクションがコミットフェーズでの予期しないクラッシュやシャットダウンを本当に許容するかどうか、また、区切られていないテキストファイル(ini、xml)をどうするかがわかりません。完全にACIDicファイルIOを手動で実装しようとするのは良い考えではないと思います。

Windowsでテキストファイルのトランザクション処理を実装するための最良の方法は何ですか?DelphiとC#の両方でこれを実行できる必要があります。

よろしくお願いします。

編集

@SirRufoのアイデアに基づいた例を見てみましょう。並行性を一瞬忘れて、クラッシュ耐性に集中しましょう。

  1. 一部のフィールドを変更するために、ファイルの内容をデータ構造に読み込みました。変更したデータをファイルに書き戻す途中で、システムがクラッシュする可能性があります。

  2. データを元のファイルに書き戻さなければ、ファイルの破損を回避できます。これは、変更が保存されるたびにファイル名にタイムスタンプが含まれる新しいファイルを作成することで簡単に実現できます。ただし、これだけでは不十分です。元のファイルはそのまま残りますが、新しく書き込まれたファイルは破損している可能性があります。

  3. タイムスタンプの後に「0」文字を付けることでこれを解決できます。これは、ファイルが検証されていないことを意味します。検証ステップで書き込みプロセスを終了します。新しいファイルを読み取り、その内容を保存しようとしているメモリ内構造と比較し、同じである場合はフラグを「1」に変更します。プログラムはファイルを読み取る必要があるたびに、ファイル名のタイムスタンプを比較して最新バージョンを選択します。最新バージョンのみを保持する必要があり、古いバージョンは削除できます。

  4. 同時実行性は、ファイルの読み取りまたは書き込みの前に名前付きミューテックスを待機することで処理できます。プログラムがファイルにアクセスするときは、ファイル名のリストをチェックすることから始めなければなりません。ファイルを読み取りたい場合は、最新バージョンを読み取ります。一方、書き込みを開始できるのは、前回読み取ったバージョンより新しいバージョンがない場合のみです。

これは大まかな、過度に単純化された、非効率的なアプローチですが、私が考えていることを示しています。ファイルの書き込みは安全ではありませんが、ファイルの破損を回避するのに役立つ上記のような簡単なトリックがあるかもしれません。

アップデート

Javaで書かれたオープンソースソリューション:

4

6 に答える 6

6

NTFS ファイル ストリームの使用はどうですか? 複数の名前付き (番号付き/タイムスタンプ付き) ストリームを同じファイル名に書き込みます。すべてのバージョンは異なるストリームに保存できますが、実際には同じ「ファイル」または一連のファイルに保存され、データを保持し、ロールバック メカニズムを提供します...確実なポイントに到達したら、以前のストリームの一部を削除します.

NT 4 で導入されましたか? すべてのバージョンをカバーしています。以前のバージョン/ストリームに加えて、復元/ロールバックする元のバージョンが常に存在するクラッシュプルーフである必要があります。

ただの深夜の思考。

http://msdn.microsoft.com/en-gb/library/windows/desktop/aa364404%28v=vs.85%29.aspx

于 2012-12-10T22:39:31.717 に答える
4

あなたが求めているのはトランザクション性です。これは、要件に応じて RDBMS データベースのメカニズムを自分で開発しないと不可能です。

「ファイル IO 中にこれらのファイルの内容を破損しないことが非常に重要です」

DBMS をピックアップします。

于 2012-12-09T23:27:23.400 に答える
1

複数のシステムにわたって独自のコードでこれらのトランザクションと状態を処理しようとすると、悪夢が生まれます。これが、ラリー・エリソン(Oracle CEO)が億万長者であり、私たちのほとんどがそうではない理由です。どうしてもファイルを使用する必要がある場合は、LOBおよびCLOBオブジェクトをサポートするOracleまたはその他のデータベースをセットアップします。非常に大きなSVGファイルを会社のこのようなテーブルに保存して、コードを変更せずにシステムに大きなマップを追加してレンダリングできるようにしています。ファイルはテーブルからプルされ、バッファ内のユーザーに渡され、完了したらデータベースに返されます。適切なセキュリティとレコードロックを設定すると、問題は解決します。

于 2012-12-15T04:33:06.623 に答える
1

まず第一に、この質問は C# や Delphi とは何の関係もありません。ファイル構造をデータベースであるかのようにシミュレートする必要があります。

仮定;

  • ファイルの移動は安価なプロセスであり、Op System は移動中にファイルが破損しないことを保証します。

  • 処理する必要があるファイルの単一のディレクトリがあります。(d:\filesDB*.*)

  • コントローラ アプリケーションは必須です。

簡素化されたワーカー プロセス。

-初期化

  1. オペレーティング システムからプロセス ID を取得します。
  2. d:\filesDB にディレクトリを作成します

    d:\filesDB\<processID>
    d:\filesDB\<processID>\inBox
    d:\filesDB\<processID>\outBox
    

・ファイルごとの処理

  1. 処理するファイルを選択します。
  2. 「inBox」ディレクトリに移動します(ファイルへの単一アクセスを保証します)
  3. ファイルを開く
  4. 「outBox」に新しいファイルを作成し、適切に閉じます
  5. 「inBox」ディレクトリ内のファイルを削除します。
  6. 「OutBox」にある新しく作成されたファイルを d:\filesDB に戻します

-ファイナライズ

  1. 作成したディレクトリを削除します。

コントローラ アプリケーション

システムの起動時にのみ実行され、作業を行うアプリケーションを初期化します。

  1. d:\filesDB ディレクトリをスキャンしてサブディレクトリを探します。
  2. サブディレクトリごとに 2.1 ファイルが「inBox」に存在する場合は、d:\filesDB に移動し、「outBox」をスキップします。2.2 「outBox」にファイルが存在する場合は、d:\filesDB に移動します。 2.3 サブディレクトリ全体を削除します。
  3. 開始する必要がある各ワーカー プロセスを開始します。

これで問題が解決することを願っています。

于 2012-12-10T15:06:10.723 に答える
1

関連記事を参照複数のスレッドで単一のファイルにアクセスする しかし、私の意見では、この種のトランザクションには Raven DB のようなデータベースを使用します。Raven DB は、同じファイルへの同時アクセスをサポートするだけでなく、複数の操作を単一の要求にバッチ処理することもサポートします。ただし、すべてがテキスト ファイルではなく、JSON ドキュメントとして保持されます。Javascript と HTML を含む .NET/C# を非常によくサポートしますが、Delphi はサポートしません。

于 2012-12-07T11:25:28.567 に答える
0

わかりました、あなたは死んでいます-XPを落とさない限り。そのように単純です。

POST-XP Windows はトランザクション NTFS をサポートしているため、.NET には公開されていません (ネイティブで使用できます)。これにより、NTFS ファイル システムで変更をロールバックまたはコミットすることができます。DTC はデータベースと連携していてもかまいません。かなりいい。ただし、XP - まさか、ありません。

トランザクショナル NTFS (TxF) に関する実際のエンタープライズ レベルの経験はありますか? スターターとして。そこの質問には、それを行う方法を開始するための多くのリソースがリストされています。

これには明らかにパフォーマンスのオーバーヘッドがあることに注意してください。ただし、2 番目のトランザクション リソースが必要でない限り、非常に薄いカーネル レベルのトランザクション コーディネーターが存在するため、トランザクションは 2 番目のリソースが追加されたときにのみ完全な DTC に昇格します。

直接リンクについては、http://msdn.microsoft.com/en-us/magazine/cc163388.aspxにすばらしい情報があります。

于 2012-12-08T19:01:42.890 に答える