Java写入Windows Server 2016时,文件上次修改时未更新

laf*_*ual 7 java java.util.logging java-10 windows-server-2016

我在Windows Server 2016上有一个Java 10应用程序,它使用java.util.logging不断写入文件.在Windows文件资源管理器中,"上次修改"和"大小"列不会更新.按[F5]不会更新详细信息.DOS DIR给出了同样错误的答案.右键单击>属性>详细信息提供了一个甚至不同(和更旧)的答案.

TYPE在文件的记事本中运行DOS 或打开/关闭(不保存),似乎导致文件资源管理器和DOS DIR更新.

我假设Java代码是正确的,flush()因为Windows Server 2008上的Java 8上的相同类导致文件资源管理器更新.另外,当运行TYPE和记事本时,我也看到与系统时钟匹配的带时间戳的记录,但在"上次修改"之后.

所以我假设Windows Server 2016有一些东西.任何想法要检查什么?

jme*_*ens 5

\n

所以我假设 Windows Server 2016 有问题。您知道要检查什么吗?

\n
\n

默认情况下,Windows 设置为以这种方式工作。从文件时间戳未在 2008 年更新但在 2003 年更新

\n
\n

2003年,在资源管理器中打开日志文件夹,您可以看到每次更新日志时时间戳和文件大小都在眼前发生变化。

\n
\n
\n

在 2008 年,大多数时候,除非你以其他方式互动,否则不会有任何变化......

\n
\n
\n

[剪]

\n
\n
\n

是的,其中一些属性已在 2008 年被禁用。\n如果您想要查看/使用 \xe2\x80\x9cLast Accessed\xe2\x80\x9d 时间,则需要启用此属性的跟踪。

\n
\n
\n

您可以通过将 HKLM\\System\\CurrentControlSet\\Control\\FileSystem\\NtfsDisableLastAccessUpdate 设置为 0(该值为 REG_DWORD)来启用此功能。

\n
\n
\n

请注意,他可能会影响繁忙文件服务器上的磁盘 IO 性能!

\n
\n

因此,改变行为是为了提高绩效。

\n

性能调优 Web 服务器

\n
\n

系统全局开关 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,则应启用此设置。

\n
\n

看来这个设置在 Windows Server 2016 中仍然可以使用。

\n
\n

我假设 Java 代码对于 flash() 是正确的,因为 Windows Server 2008 上的 Java 8 上的相同类会导致文件资源管理器更新。此外,在运行 TYPE 和记事本时,我还看到与系统时钟匹配的时间戳记录,但在“上次修改”之后。

\n
\n

Flush 与sync 不同。仅FileHandler在发布每条记录后执行刷新。Windows 未设置为强制将元数据写入文件系统。从文件 \xe2\x80\x9cDate 修改\xe2\x80\x9d 属性在修改文件而不关闭它时不会更新。:

\n
\n

在 2008 年,日志文件上的“上次修改时间”字段不会更新,除非另一个程序尝试打开该文件或停止实用程序,即使按 F5 刷新视图也是如此。

\n
\n
\n

Explorer 从 NTFS 获取信息,通过使用 cmd 提示符和“dir”,我们发现文件的 NTFS 元数据在文件句柄关闭之前不会更新。

\n
\n
\n

刷新文件夹的信息只是转到 NTFS 缓存的(驻留在内存中的)元数据,但显式查询文件将强制磁盘 I/O 获取属性 - 这是 Vista 中引入的设计更改,以减少不必要的磁盘I/O 以提高性能

\n
\n
\n

此规则有一些例外:

\n
\n
    \n
  • 在某些情况下(但不是全部),简单的“dir 文件名”足以刷新元数据
  • \n
  • “特殊”文件夹可能会受到不同的对待,例如我们不希望有大量文件但希望能够依赖所提供的文件数据的用户配置文件
  • \n
  • 内核过滤器驱动程序可能会更改行为,因为根据设计它们“添加、删除或\n更改其他驱动程序的功能”
  • \n
\n
\n

由于解决方法是让任何进程打开和关闭日志文件的句柄,因此编写了一个工具来完成此操作,并使用以下 API 获取文件信息:

\n
\n
    \n
  • 创建文件
  • \n
  • 通过句柄获取文件信息
  • \n
  • 关闭句柄
  • \n
\n

您可以尝试使用 FileHandler 创建的文件名打开 FileInputStream。

\n
\n

仅在文件上运行 DOS TYPE 或在记事本中打开/关闭(不保存),似乎会导致文件资源管理器和 DOS DIR 更新。

\n
\n

我发现从外部进程更新元数据的唯一通用方法是使用文件资源管理器交互地选择文件

\n
explorer /select, c:\\test\\file.txt\n
Run Code Online (Sandbox Code Playgroud)\n

这很可能与记事本中发生的情况非常相似。

\n

我喜欢你使用TYPE命令的方式。您可以将其与nul一起使用来忽略输出。

\n
type filename.log > NUL\n
Run Code Online (Sandbox Code Playgroud)\n

使用元数据开关运行可能dir会强制更新元数据:

\n
dir /A /R /Q filename.log > nul\n
Run Code Online (Sandbox Code Playgroud)\n