簡體   English   中英

Java 寫入 Windows Server 2016 時文件上次修改未更新

[英]File Last Modified Not Updating when Java Writes to Windows Server 2016

我在 Windows Server 2016 上有一個 Java 10 應用程序,它使用 java.util.logging 不斷寫入文件。 在 Windows 文件資源管理器中,“上次修改時間”和“大小”列不會更新。 按 [F5] 不會更新詳細信息。 DOS DIR給出了同樣的錯誤答案。 gives an even different (and older) answer.給出了一個甚至不同(和更舊)的答案。

僅在記事本中對文件運行 DOS TYPE或打開/關閉(不保存),似乎會導致文件資源管理器和 DOS DIR更新。

我假設 Java 代碼關於flush()是正確的,因為 Windows Server 2008 上的 Java 8 上的相同類會導致文件資源管理器更新。 同樣在運行TYPE和記事本時,我也看到與系統時鍾匹配的時間戳記錄,但在“上次修改”之后。

所以我假設 Windows Server 2016 有問題。有什么想法要檢查嗎?

所以我假設 Windows Server 2016 有問題。有什么想法要檢查嗎?

默認情況下,Windows 設置為以這種方式工作。 文件時間戳未在 2008 年更新但在 2003 年更新

2003年,在資源管理器中打開日志文件夾,每次更新日志時,都可以在眼前看到時間戳和文件大小的變化。

在 2008 年,大多數情況下,除非您以其他方式進行交互,否則不會發生任何變化......

[剪輯]

是的,其中一些屬性在 2008 年已被禁用。例如,如果您想查看/使用“上次訪問”時間,則需要啟用此屬性的跟蹤。

您可以通過將 HKLM\\System\\CurrentControlSet\\Control\\FileSystem\\NtfsDisableLastAccessUpdate 設置為 0(此值為 REG_DWORD)來啟用此功能。

請注意,他可能會影響繁忙的文件服務器上的磁盤 IO 性能!

所以行為是為了提高性能而改變的。

性能調優 Web 服務器

系統全局開關 NtfsDisableLastAccessUpdate (REG_DWORD) 1 位於 HKLM\\System\\CurrentControlSet\\Control\\FileSystem 下,默認設置為 1。此開關通過禁用最后一次的日期和時間戳更新來減少磁盤 I/O 負載和延遲文件或目錄訪問。 Windows Server 2016、Windows Server 2012 R2、Windows Server 2012、Windows Server 2008 R2 和 Windows Server 2008 的全新安裝默認啟用此設置,您無需調整它。 早期版本的 Windows 沒有設置這個鍵。 如果您的服務器運行的是較早版本的 Windows,或者已升級到 Windows Server 2016、Windows Server 2012 R2、Windows Server 2012、Windows Server 2008 R2 或 Windows Server 2008,則應啟用此設置。

看來此設置仍可在 Windows Server 2016 中使用。

我假設 Java 代碼關於 flush() 是正確的,因為 Windows Server 2008 上的 Java 8 上的相同類會導致文件資源管理器更新。 同樣在運行 TYPE 和記事本時,我還看到與系統時鍾匹配的時間戳記錄,但在“上次修改”之后。

Flush 與 sync 不同 FileHandler只是在每條記錄發布后執行刷新。 Windows 未設置為強制將元數據寫入文件系統。 文件“修改日期”屬性在修改文件而不關閉它時不會更新。

在 2008 年,日志文件上的“上次修改”字段不會更新,除非另一個程序嘗試打開該文件或該實用程序被停止,即使按 F5 刷新視圖也是如此。

資源管理器從 NTFS 獲取信息,通過使用 cmd 提示符和“dir”,我們發現文件的 NTFS 元數據在文件句柄關閉之前不會更新。

刷新一個 FOLDER 的信息只會轉到 NTFS 緩存的(內存駐留)元數據,但是顯式查詢文件將強制磁盤 I/O 獲取屬性 - 這是 Vista 中引入的設計更改以減少不必要的磁盤用於提高性能的 I/O

此規則有一些例外:

  • 在某些情況下,但不是全部,一個簡單的“目錄文件名”就足以刷新元數據
  • “特殊”文件夾可能會有不同的處理方式,例如我們不希望有大量文件並希望能夠依賴所提供的文件數據的用戶配置文件
  • 內核過濾器驅動程序可能會改變行為,因為它們按照設計“添加、刪除或更改其他驅動程序的功能”

由於解決方法是讓任何進程打開和關閉日志文件的句柄,因此編寫了一個工具來做到這一點,並使用以下 API 獲取文件信息:

  • 創建文件
  • GetFileInformationByHandle
  • 關閉句柄

您可以嘗試使用 FileHandler 創建的文件名打開 FileInputStream。

僅在記事本中對文件運行 DOS TYPE 或打開/關閉(不保存),似乎會導致文件資源管理器和 DOS DIR 更新。

我發現從外部進程更新元數據的唯一通用方法是使用文件資源管理器以交互方式選擇文件

explorer /select, c:\test\file.txt

這很可能與記事本中發生的情況非常相似。

我喜歡你使用TYPE命令。 您可以將其與nul一起使用以忽略輸出。

type filename.log > NUL

使用元數據開關運行dir可能會強制更新元數據:

dir /A /R /Q filename.log > nul

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM