質問

ディレクトリツリーの変更を監視する必要がある Java プログラムがあります。を使用するJNIコードがあります ReadDirectoryChangesW(). 。ディレクトリは次のように開きます。

HANDLE dirHandle = CreateFile(
    path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
);

そして私は通ります dirHandleReadDirectoryChangesW(). 。それはすべてうまくいきます。

問題は、コードの他の部分 (Java 側) で File.setLastModified() ファイルまたはディレクトリを「タッチ」します (タイムスタンプを「現在」に更新します)。これは通常は機能します。ただし、次の方法で開かれたディレクトリに「タッチ」しようとすると失敗します。 CreateFile().

実際にどのような Windows エラーが発生しているのかを確認するために、JDK ソースを調べました。 File.setLastModified() そして、からのエラーを出力することを追加して、自分のコードで再実装しました。 GetLastError();エラーは次のとおりです。

ERROR_SHARING_VIOLATION (error 32)
"The process cannot access the file because it is being used by another process."

なんと?それは 同じ プロセス。私も合格しました FILE_SHARE_READ そして FILE_SHARE_WRITECreateFile().

これを機能させる方法はありますか?

より詳しい情報

ネイティブコードの実装は、 File.setLastModified() JDK では次の処理が行われます。

h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);

最初を変更すると 0FILE_SHARE_READ | FILE_SHARE_WRITE, 、すべて機能します。そのため、JDK の実装が少し壊れているようです。:(

したがって、私の質問は次のようになります。私自身の(再)実装を使用せずにこれを機能させる方法はありますか File.setLastModified()?

役に立ちましたか?

解決

この場合、エラー メッセージは少し誤解を招きますが、表示されているのは通常の動作です。

次のコマンドでディレクトリを開くと、 dwShareMode ゼロに設定すると、JDK は実質的に排他的アクセスを要求することになり、他のアクセス試行は共有違反エラーで失敗します。これはアクセスにも同様に適用される。 他のプロセスからも、自分のプロセス内からも。

CreateFile ドキュメンテーション について説明します dwShareMode パラメータ:

このパラメーターがゼロで CreateFile が成功した場合、ファイルまたはデバイスは共有できず、ファイルまたはデバイスのハンドルが閉じられるまで再度開くことはできません。

ハンドルが開いている既存のリクエストで指定されているアクセス モードと競合する共有モードをリクエストすることはできません。 CreateFile 失敗するだろうし、 GetLastError 関数は返すでしょう ERROR_SHARING_VIOLATION.

それで、あなたはあなた自身の質問に答えたようです:カスタムが必要です setLastModified を指定する関数 FILE_SHARE_READ | FILE_SHARE_WRITE ディレクトリにアクセスするとき。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top