7

FileLockを使用して Windows 環境で Java を使用してファイルをロックしようとしていますが、問題が発生しました。ファイルをロックした後でも、少なくともある程度のレベルで他のプロセスからアクセスできます。

コード例は次のとおりです。

public class SimpleLockExample {
    public static void main(String[] args) throws Exception {
        String filename = "loremlipsum.txt";

        File file = new File(filename);
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        FileChannel channel = raf.getChannel();

        FileLock lock = null;
        try {
            lock = channel.tryLock();
            String firstLine = raf.readLine();
            System.out.println("First line of file : " + firstLine);
            waitForEnter();
            lock.release();
        } catch (OverlappingFileLockException e) {
            e.printStackTrace();
        }

        lock.release();
        System.out.println("Lock released");

        channel.close();
    }

    private static void waitForEnter() throws Exception {
        BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in));
        reader.readLine();
        reader.close();
    }
}

さて、この例でファイルをロックすると、ロックされます:

  • Windows では削除できません。
  • Eclipseはそれを開くことを拒否します

...しかし、まだ完全に防弾というわけではありません:

  • たとえば、Scite (テキスト エディター) で開いた場合、コンテンツは表示されませんが、ファイルを保存することを選択した場合 (開いたときに空であるか、いくつかのコンテンツが書き込まれている)、成功し、ファイルの内容がクリアされます.. . (Scite で何かを書いたとしても、その後にコンテンツは存在しません)

Windows で Java を使用している他のプロセスによってファイルが完全に上書き/消去されるのを防ぐ方法はありますか?

私の理解が正しければ、私は専用ロックATMを使用しています。共有ロックを使用すると、さらに多くのことができます。

このテストは Windows 2000 で実行されました。

br, トウコ

4

2 に答える 2

5

注意が必要なのは、FileLock API 自体があまり約束していないことです。

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

ロックによって別のプログラムがロックされた領域のコンテンツにアクセスするのを実際に防止するかどうかは、システムに依存するため未指定です。一部のシステムのネイティブ ファイル ロック機能は単なる助言にすぎません。つまり、プログラムは、データの整合性を保証するために、既知のロック プロトコルを協力して監視する必要があります。他のシステムでは、ネイティブ ファイル ロックが必須です。つまり、あるプログラムがファイルの領域をロックすると、他のプログラムはロックに違反するような方法でその領域にアクセスできなくなります。さらに他のシステムでは、ネイティブ ファイル ロックが推奨か強制かをファイルごとに設定できます。プラットフォーム間で一貫した正しい動作を確保するには、

奇妙なことに、開発中のファイル ロック API に関する議論では、Windows OS は必須のロックを提供し、Unix ではアドバイザリー ロックのみを提供すると主張していました。したがって、これを読むと、コードが Windows 上で問題なく動作することが期待されるかもしれません。

エディターがファイルを変更するのではなく、一時ファイルを作成してから、ロックしたファイルのバージョンを新しいバージョンに置き換えるためにディレクトリ エントリを操作しているのに、何が起こっているのだろうかと思います。Windows はそのような動作を許可しますか?

必要なレベルの制御を得るために、JNI に頼る必要があるのではないかと思います。

于 2009-08-27T07:18:13.017 に答える
1

.tryLock() への呼び出しは、ロックを取得しない場合、null を返すことがあります。Javadoc から:

新しく取得したロックを表すロック オブジェクト、または別のプログラムが重複するロックを保持しているためにロックを取得できなかった場合は null

また、コードは現在ファイル開き、ロックを取得しようとしています。代わりに、ロックを取得しようとしてループする必要があります。ロックを取得したら、ファイルを開き、ファイルを読み取り、ファイルを閉じてから、ロックを放棄します。finally {}また、ロックが保持されている状態でコードが例外をスローした場合に備えて、節でロックを放棄します。(一部のファイルがロックされたという理由だけで、Windows マシンを再起動しなければならなかったことはありませんか?)

于 2010-03-23T16:38:25.670 に答える