2010-04-27 32 views
2

我使用JPoller來檢測特定目錄中文件的更改,而是因爲他們結束了一個時間戳早於他們的實際創建它的文件丟失時間。以下是我測試:file.createNewFile()創建的文件與實際創建時間之前的最後一次修改時間

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. JPoller忽略新加入的文件,因爲XYZ ... 000小於XYZ ... 123
  6. 我拉我的頭髮了一會兒

我試圖挖掘到的代碼,但兩者lastModified()createNewFile()最終下定決心,本地調用,所以我留下了很少的信息。對於test.9我輸了957毫秒。我可以期待什麼樣的準確度?我的結果會因操作系統或文件系統而異?建議的解決方法?

注:我目前正在與XFS文件系統上運行Linux。我在C寫了一個快速程序和stat system call顯示st_mtime作爲truncate(xyz...000/1000)

更新:我跑了相同的節目,我上面有在Windows 7上使用NTFS,它保持充分的誤差在毫秒級。@mdma提供了進一步的說明,FAT文件系統對於以10毫秒分辨率創建時是準確的,但訪問僅準確到2秒。因此,這完全取決於操作系統。

+0

這可能與某人有關......當在Linux和javas上使用XFS lastModified()時,它始終以相同的時間返回(1.8.0_131-b11) – Zarathustra 2017-06-12 16:01:30

回答

2

文件系統不會不毫秒的分辨率,例如存儲時間精確,常FAT有2秒的創建時間分辨率,而NTFS可以延遲最近一次訪問時間的更新達1小時。 (有關MSDN的詳細信息。)雖然不是,但通常情況下,如果文件是在另一臺計算機上創建的,則還存在同步時鐘的問題。

看來,這可能是爲JPoller人的問題,因爲這是時的處理邏輯。在解決此問題之前,您可以通過手動將每個寫入的文件的最後修改時間設置爲距實際時間+4秒來解決此問題 - +4是一個任意值,應該大於您正在處理的文件系統的分辨率。將文件寫入文件系統時,它們將向下舍入,但小於您添加的值。不漂亮,但它會工作!

+0

尼斯鏈接。它看起來像NTFS會給我更好的分辨率(高達100納秒)。可悲的是,這意味着這絕對取決於操作系統,實施跨平臺修復不會非常簡單。 – 2010-04-27 16:40:58

2

上次修改的時間戳顯然存儲在秒,不以毫秒爲單位。這可能是一個文件系統限制。我建議比較它與秒而不是毫秒。

+0

Linux本身沒有創建時間戳; 'st_mtime'是inode最後一次被修改的時間。 – Gabe 2010-04-27 01:09:58

+0

@加貝:我用錯了措辭,修正了。 – BalusC 2010-04-27 01:14:08

+0

這不是文件系統的限制;這可能是API的限制。 XFS支持多年的毫秒時間戳,但Java庫函數可能不知道如何提取它。 – Gabe 2010-04-27 03:23:46