3

ファイルのセットがあります。ファイルのセットは、NTFS 共有からは読み取り専用であるため、多くのリーダーを持つことができます。各ファイルは、書き込みアクセス権を持つ 1 つのライターによって時々更新されます。

次のことを確認するにはどうすればよいですか。

  1. 書き込みが失敗した場合、以前のファイルがまだ読み取り可能であること
  2. 読者は単一の作家を保持することはできません

私はJavaを使用していますが、現在の解決策は、ライターが一時ファイルに書き込み、File.renameTo(). 問題は NTFS にあり、renameToターゲット ファイルが既に存在する場合は失敗するため、自分で削除する必要があります。しかし、ライターがターゲット ファイルを削除してから失敗した場合 (コンピューター クラッシュ)、読み取り可能なファイルがありません。

nio の FileLock は同じ JVM でしか機能しないため、私には役に立ちません。

Java を使用して多くのリーダーでファイルを安全に更新するにはどうすればよいですか?

4

6 に答える 6

3

JavaDocによると:

このファイル ロック API は、基盤となるオペレーティング システムのネイティブ ロック機能に直接マップすることを目的としています。したがって、ファイルに保持されているロックは、プログラムが記述されている言語に関係なく、ファイルにアクセスできるすべてのプログラムから見える必要があります。

于 2009-01-07T18:15:42.460 に答える
1

これが当てはまるかどうかはわかりませんが、純粋な Vista/Windows Server 2008 ソリューションで実行している場合は、TxF (トランザクション NTFS) を使用し、ファイル ハンドルを開いて、 JNI を介した適切なファイル API。

それができない場合は、すべてのクライアントがアクセスし、ファイルの読み取り/書き込みを調整する役割を担う何らかのサービスが必要だと思います。

于 2009-01-07T18:12:52.090 に答える
1

Unix システムでは、ファイルを削除してから書き込み用に開きます。読み取り用に開いていた人は、まだ古いものを見ることができ、全員がそれを閉じると、ファイル システムから消えてしまいます。NTFS に同様のセマンティクスがあるかどうかはわかりませんが、BSD のファイル システムにかなり基づいていると聞いているので、そうかもしれません。

于 2009-01-07T18:17:17.683 に答える
1

OSなどに関係なく、常に機能するはずの何かが、クライアントソフトウェアを変更しています。

これがオプションである場合は、ファイル「settings1.ini」を使用できます。それを変更する場合は、ファイル「settings2.ini.wait」を作成し、それに自分の内容を書き込んでから「settings2」に名前を変更します.ini」を削除し、「settings1.ini」を削除します。

変更されたクライアント ソフトウェアは、最後に settings1.ini を読み取った場合は常に settings2.ini をチェックし、その逆も同様です。

このようにして、常に作業コピーがあります。

于 2009-01-07T19:29:26.663 に答える
0

ロックする必要はないかもしれません。私は Windows の FS API にあまり詳しくありませんが、NTFS はハード リンクとソフト リンクの両方をサポートしているため、セットアップで許可されている場合は、これを試すことができます。

ハード リンクまたはソフト リンクを使用して実際のファイルを指し、ファイルに別の名前を付けます。リンクの名前を使用して全員がファイルにアクセスできるようにします。

新しいファイルを別の名前で同じフォルダーに書き込みます。

完了したら、ファイルが新しいファイルを指すようにします。Windows では、1 つのアトミック操作で既存のリンクを置き換えて新しいリンクを作成できることが最適です。そうすれば、リンクが常に有効なファイル (古いファイルまたは新しいファイル) を識別できるようになります。最悪の場合、最初に古いファイルを削除してから、新しいファイルへのリンクを作成する必要があります。その場合、プログラムがファイルを見つけることができない短い期間があります。(また、Mac OS X は、2 つの項目をアトミックに交換できる「ExchangeObjects」機能を提供します。Windows も同様の機能を提供する可能性があります)。

このようにして、古いファイルが既に開かれているプログラムは引き続き古いファイルにアクセスし、新しいファイルを作成する邪魔になりません。アプリが新しいバージョンの存在に気付いた場合にのみ、現在のバージョンを閉じて再度開くことができ、この方法で新しいバージョンにアクセスできます。

ただし、Java でリンクを作成する方法がわかりません。そのためには、ネイティブ API を使用する必要があるかもしれません。

とにかくこれが役立つことを願っています。

于 2009-01-07T18:26:35.667 に答える
-1

私は最近似たようなことを扱っています。Java 5 を実行している場合、ReentrantReadWriteLock と組み合わせて NIO ファイル ロックを使用することを検討できますか? FileChannel オブジェクトを参照するすべてのコードが ReentrantReadWriteLock も参照していることを確認してください。このようにして、NIO は VM ごとのレベルでロックし、再入可能ロックはスレッドごとのレベルでロックします。

FileLock fileLock = filechannel.lock(position, size, shared);
reentrantReadWriteLock.lock();

// do stuff

fileLock.release();
reentrantReadWriteLock.unlock();

もちろん、いくつかの例外処理が必要になります。

于 2009-01-07T18:19:15.587 に答える