2009-09-19 12 views
18

當我在正在寫入的文件上調用FileInfo(path).LastAccessTimeFileInfo(path).LastWriteTime時,它將返回文件創建的時間,而不是最後一次寫入的時間(即現在)。.NET FileInfo.LastWriteTime&FileInfo.LastAccessTime是錯誤的

有沒有辦法得到這些信息?

編輯:到目前爲止的所有回覆。我沒有試過Refresh(),但那也沒有做到。我返回了文件開始寫入的時間。靜態方法也是如此,並創建了一個FileInfo的新實例。

Codymanix可能有答案,但我沒有運行Windows Server(使用Windows 7),我不知道該設置要測試的位置。

編輯2:沒有人覺得這個功能似乎不起作用有趣嗎?

+0

我也發現這些函數給出不可靠的信息;就像文件駐留在(samba)網絡共享上時一樣。我注意到MSDN文檔(http://msdn.microsoft.com/en-us/library/system.io.file.getlastaccesstime(v=VS.90).aspx)現在說「這種方法可能會返回一個不準確的值.. 。「 – 2011-07-26 18:38:42

回答

3

您是否在訪問屬性之前嘗試調用Refresh()(以避免獲取緩存的值)?如果這不起作用,你有沒有看過Explorer同時顯示的內容?如果資源管理器顯示錯誤的信息,那麼這可能是您無法真正解決的問題 - 例如,可能只是在文件句柄關閉時更新信息。

14

FileInfo值只加載一次,然後緩存。爲了得到當前值,調用Refresh()得到一個屬性之前:

f.Refresh(); 
t = f.LastAccessTime; 

另一種方式來獲得的電流值是通過使用在File類的靜態方法:

t = File.GetLastAccessTime(path); 
+0

t = File.GetLastAccessTime(path);如果進程已保存但鎖定文件仍然過期。這個答案是不正確的。 – rolls 2017-07-26 08:02:18

4

從MSDN:

第一次調用時,FileSystemInfo 調用Refresh並在API上返回 緩存的信息以獲得 屬性等。在隨後的 調用中,您必須調用Refresh獲取 的最新信息副本。

FileSystemInfo.Refresh()

如果你的應用是一個做寫作,我認爲你將不得不「觸摸」通過設置LastWriteTime屬性你寫的每個數據緩衝區之間你自己的文件。一些僞代碼:

while(bytesWritten < totalBytes) 
{ 
    bytesWritten += br.Write(buffer); 
    myFileInfo.LastWriteTime = DateTime.Now; 
} 

我不確定這會嚴重影響寫入性能。

4

在Windows中有一個設置,有時在服務器系統上特別設置,所以文件的修改和訪問時間未設置爲更好的性能。

+0

codymanix是對的,他們在這裏談論這個設置:http://blogs.technet.com/b/filecab/archive/2006/11/07/disabling-last-access-time-in-windows-vista-to- improve-ntfs-performance.aspx – DukeOfMarmalade 2012-04-03 12:22:20

+0

該鏈接僅提及上次修改時間。 – 2013-03-21 14:47:16

0

湯米CARLIER的回答讓我思考....

一個很好的方式來形象化差異是單獨運行兩個片段(我剛剛使用LinqPAD),同時還運行sysinternals進程監視器。

while(true) 
    File.GetLastAccessTime([file path here]); 

FileInfo bob = new FileInfo(path); 

while(true){ 
    string accessed = bob.LastAccessTime.ToString(); 
} 

如果你看看進程監視器運行時,你會看到重複的第一個片段,不斷訪問嘗試爲LinqPAD過程中的文件。第二個片段將對文件進行初始訪問,對此您將在進程監視器中看到活動,然後很少。

但是,如果你去修改文件(我剛剛打開了我使用FileInfo監視的文本文件並添加了一個字符並保存),您將看到LinqPAD進程對進程監視器中的文件進行的一系列訪問嘗試。

這分別說明了兩種不同方法的非高速緩存和高速緩存行爲。

非高速緩存的方法會在硬盤上留下一個洞嗎?

編輯

我離開的感覺高明在我的測試,然後用在我的Windows服務的FileInfo的緩存行爲(基本上在一個循環中坐,並說「有文件改變的,人─文件更改......「)

雖然這種方法在我的開發箱中工作,但它在生產環境中不起作用,即無論文件是否更改,流程都保持運行。我最終改變了檢查方法,並將GetLastAccessTime作爲其一部分。不知道爲什麼它會在生產服務器上有不同的表現......但我在這一點上並不太在意。

+0

最終是,以及時間和空間。 – PsyKzz 2012-12-09 18:53:25

2

正如詹姆斯指出的,LastAccessTime沒有更新。

自Vista以來,LastWriteTime也經歷了一次轉折。當進程有文件仍然打開並且另一個進程檢查LastWriteTime時,它將不會看到長時間的新寫入時間,直到進程關閉文件。 作爲解決方法,您可以從外部進程打開和關閉該文件。完成之後,您可以嘗試再次讀取LastWriteTime,然後這是最新的值。

如果應用程序實現了類似滾動記錄器那樣關閉文件,然後將其重命名爲其他文件名,您也將遇到問題,因爲操作系統會記住「舊」文件的創建時間和文件大小盡管你確實創建了一個新文件。這包括錯誤的文件大小報告,即使您重新創建了仍然爲0字節大小的log.txt。此功能稱爲OS文件系統隧道,它仍然存在於Windows 8.1上。有關如何實施此問題的示例,請查看企業庫中的RollingFlatFileTracelistener(http://home.elka.pw.edu.pl/~mrudnik/CREAM/Logging/Src/Logging/TraceListeners/RollingFlatFileTraceListener.cs)。

您可以從cmd shell中看到文件系統隧道對自己機器的影響。

echo test > file1.txt 
ren file1.txt file2.txt 
Wait one minute 
echo test > file1.txt 

dir /tc file*.txt 
... 
05.07.2015 19:26     7 file1.txt 
05.07.2015 19:26     7 file2.txt 

該文件系統是一個狀態機。如果你關心性能和正確性,保持狀態正確同步是很困難的。 這種奇怪的隧道綜合徵顯然仍然被應用程序所使用,例如,自動保存文件並將其移至保存位置,然後在同一位置再次重新創建文件。對於這些應用程序來說,它賦予文件一個新的創建日期是有意義的,因爲它僅被複制。某些安裝程序也會將這些技巧臨時移動到不同的位置,並稍後將內容寫回以便通過某些文件存在檢查某些安裝掛鉤。