2

JPollerを使用して特定のディレクトリ内のファイルへの変更を検出していますが、実際の作成時刻よりも前のタイムスタンプで終わるため、ファイルが見つかりません。テスト方法は次のとおりです。

public static void main(String [] files)
{
    for (String file : files)
    {
        File f = new File(file);
        if (f.exists())
        {
            System.err.println(file + " exists");
            continue;
        }

        try
        {
            // find out the current time, I would hope to assume that the last-modified
            // time on the file will definitely be later than this
            System.out.println("-----------------------------------------");
            long time = System.currentTimeMillis();

            // create the file
            System.out.println("Creating " + file + " at " + time);
            f.createNewFile();

            // let's see what the timestamp actually is (I've only seen it <time)
            System.out.println(file + " was last modified at: " + f.lastModified());

            // well, ok, what if I explicitly set it to time?
            f.setLastModified(time);
            System.out.println("Updated modified time on " + file + " to " + time + " with actual " + f.lastModified());
        }
        catch (IOException e)
        {
            System.err.println("Unable to create file");
        }
    }
}

そして、これが私が出力のために得るものです:

-----------------------------------------
Creating test.7 at 1272324597956
test.7 was last modified at: 1272324597000
Updated modified time on test.7 to 1272324597956 with actual 1272324597000
-----------------------------------------
Creating test.8 at 1272324597957
test.8 was last modified at: 1272324597000
Updated modified time on test.8 to 1272324597957 with actual 1272324597000
-----------------------------------------
Creating test.9 at 1272324597957
test.9 was last modified at: 1272324597000
Updated modified time on test.9 to 1272324597957 with actual 1272324597000

結果は競合状態です:

  1. JPollerは最後のチェックの時間をxyzとして記録します...123
  2. xyzで作成されたファイル...456
  3. ファイルの最終変更タイムスタンプは実際にはxyz...000を読み取ります
  4. JPollerは、タイムスタンプがxyz...123より大きい新しい/更新されたファイルを探します
  5. xyz...000はxyz...123より小さいため、JPollerは新しく追加されたファイルを無視します
  6. しばらく髪を抜く

コードを掘り下げてみましたが、どちらlastModified()createNewFile()最終的にはネイティブコールに解決されるため、情報がほとんど残っていません。

の場合test.9私は957ミリ秒を失います。どのような精度が期待できますか?結果はオペレーティングシステムやファイルシステムによって異なりますか?推奨される回避策は?

注:現在、XFSファイルシステムを使用してLinuxを実行しています。でクイックプログラムを作成しましCたが、statシステムの呼び出しst_mtimeとして表示されtruncate(xyz...000/1000)ます。

更新:NTFSを使用するWindows 7で上記と同じプログラムを実行しましたが、完全なミリ秒の精度が維持されます。MSDNリンク@mdmaは、FATファイルシステムが10ミリ秒の解像度で作成する場合は正確ですが、アクセスは2秒までしか正確ではないことをさらに示しています。したがって、これは本当にOSに依存します。

4

2 に答える 2

2

ファイルシステムは時間を正確に保存せず、多くの場合ミリ秒の解像度ではありません。たとえば、FATの作成時間の解像度は2秒であり、NTFSは最終アクセス時間の更新を最大1時間遅らせることができます。(MSDNの詳細。)あなたの場合ではありませんが、一般に、ファイルが別のコンピューターで作成されている場合、クロックの同期の問題もあります。

これは、時間処理ロジックがある場所であるため、JPollerの人々にとって問題になる可能性があります。修正されるまでは、書き込まれた各ファイルの最終変更時刻を実際の時刻から+4秒に手動で設定することでこれを回避できます。+ 4は任意の値であり、作業中のファイルシステムの解像度よりも大きくする必要があります。ファイルがファイルシステムに書き込まれるとき、それらは切り捨てられますが、追加した値よりも少なくなります。きれいではありませんが、うまくいきます!

于 2010-04-27T02:20:53.353 に答える
2

最終的に変更されたタイムスタンプは、ミリ秒単位ではなく秒単位で保存されているようです。これはファイルシステムの制限である可能性があります。ミリ秒ではなく秒と比較することをお勧めします。

于 2010-04-27T00:51:05.610 に答える