Windows 文件共享:为啥有时新创建的文件在一段时间内不可见?

Posted

技术标签:

【中文标题】Windows 文件共享:为啥有时新创建的文件在一段时间内不可见?【英文标题】:Windows file share: why sometimes newly created files aren't visible for some period of time?Windows 文件共享:为什么有时新创建的文件在一段时间内不可见? 【发布时间】:2011-07-06 18:20:30 【问题描述】:

我们遇到了非常奇怪的问题,这让我们发疯了。有时,我们的文件共享 PC 上新创建的文件在一段时间内“不存在”。要重现问题,您至少应该拥有两台计算机,分别调用它们alphabeta。在beta PC (\\beta\share\bug) 上创建文件共享并从alpha PC 运行此 PowerShell 脚本:

param(
  $sharePath="\\beta\share\bug"
)
$sharePC = ($sharePath -split '\\')[2]
$session = New-PSSession -ComputerName $sharePC
$counter = 0
while ($true) 
  $fileName = $sharePath + "\$counter.txt"
  Invoke-Command -Session $session -ScriptBlock 
    param(
      $fileName
    )
    "" > $fileName
   -ArgumentList $fileName
  if (Test-Path $fileName) 
    Write-Host "File $fileName exists" -fore Green
   else 
    Write-Host "!!! File $fileName does NOT exist!" -fore Red
  

  $counter = $counter + 1
  Start-Sleep 2

启动此脚本后,您应该能够看到以下消息:

File \\beta\share\bug\1.txt exists
File \\beta\share\bug\2.txt exists
...

现在: 打开cmd.exe 并运行以下命令:

if exist \\beta\share\bug\foo.txt echo 1

在此之后大约 10 秒内,您将看到以下消息:

!!! File \\beta\share\bug\3.txt does NOT exist!
!!! File \\beta\share\bug\4.txt does NOT exist!

我们发现该错误是由枚举正在创建新文件的共享目录引起的。在Python 中调用os.listdir('//beta/share/bug') 以重现错误。在C#Directory.GetDirectories(@"\\beta\share\bug")。您甚至可以简单地通过 shell 导航到共享目录并调用 lsdir

Windows Server 2008 R2 上发现了错误

请注意,您不能在Windows Explorer 中实时查看alpha PC 上的目录内容,因为如果您在资源管理器中打开此目录,则不会出现错误!因此,请确保在尝试重现错误之前关闭所有此类窗口。每次脚本重新启动后,您应该手动从共享中删除所有已创建的文件(因为脚本相当愚蠢并且总是从 0.txt 开始)。

我们目前有 2 个解决此问题的方法:

    如果客户看到这种情况,它会在有问题的目录中创建一些临时文件 - 在这些文件神奇地出现之后。 禁用 SMB 2.0:http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm

有没有人发现过类似的问题并能解释为什么会发生以及如何“正确解决”它?

谢谢

【问题讨论】:

您是否查看过网络跟踪以了解发生了什么? 不,很遗憾我没有查看网络跟踪 我认为网络跟踪不会有帮助。这似乎是服务器端的缓存问题。从 Windows 2003 迁移到 2012R2 时,我们遇到了完全相同的问题。似乎 SMB 显示了创建它们的服务器的文件,但随后显示这些文件对于查询它们的其他服务器尚不存在。这很糟糕。 【参考方案1】:

一个月过去了,没有答案……

所以,我们坚持使用“Disable SMB 2.0”解决方案。至少它有效。

http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm

【讨论】:

【参考方案2】:

我遇到了类似的问题,最终我找到了导致此问题的原因。具体问题是SMB2 Directory Cache,是SMB2 Client Redirector cache components之一:

这是客户端最近执行的目录枚举的缓存。客户端应用程序发出的后续枚举请求以及对目录中文件的元数据查询可以从缓存中得到满足。客户端还使用目录缓存来确定目录中是否存在文件,并使用该信息来防止客户端重复尝试打开服务器上已知不存在的文件。此缓存可能会影响在访问服务器上的一组文件的多台计算机上运行的分布式应用程序 - 其中应用程序使用带外机制相互通知服务器上文件的修改/添加/删除。

这个美妙的小缓存的默认值为 10 秒,这会产生您所看到的行为。当您的代码向系统询问有关该目录/文件的信息时,它会获得 10 秒前的缓存结果,因此它说该文件不存在。将HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime (DWORD) 设置为0 值将禁用缓存并解决文件不存在问题。令人惊讶的是,此更改需要重新启动客户端计算机!这也将允许您保持启用 SMB2,由于多种原因,这应该比强制 SMB1 更好。

此外,当在 Windows 资源管理器中打开相关共享时,不会使用缓存,因为打开它会告诉系统绕过缓存以保持实时视图继续进行。但是,通过代码修改共享中的某些内容不会。

我认为这整个问题在 Windows 2008 R2/7 及更高版本中已得到解决,但我不能绝对确认。这在现代版本的 Windows 中仍然是一个问题。有关详细信息,请参阅下面的 cmets。

【讨论】:

在 2008R2 及更高版本中未修复。事实上,这在 Windows 2012R2 中仍然是一个问题。 顺便说一句,此解决方案解决了机器通过 SMB 共享访问 Windows 2012R2 的问题。谢谢贾斯汀,您在这里的信息非常有价值! @Brain2000 感谢您确认这在以后的版本中仍然存在。 我仍然发现这是 Windows 8.1 中的一个问题。 最近开始在 Windows 10 中遇到此问题。这为我解决了问题【参考方案3】:

Windows 7 SP1 中还有一个错误,有可用的修补程序

File that a user adds to a remote folder is not displayed in Windows Explorer on a computer that is running Windows 7 or Windows Server 2008 R2

【讨论】:

【参考方案4】:

解决此问题的最简单方法(根据 OP 的建议)是在您希望文件出现的文件夹中创建一个临时文件或子文件夹,然后立即将其删除。这会触发更改变得可见。

我们注意到在文件夹中添加 FileSystemWatcher 也有帮助,即使它什么都不做。

【讨论】:

听起来很可笑,这对我来说是最简单的答案(我是作为用户浏览,而不是自动化)【参考方案5】:

您可以使用神奇的后缀$NOCSC$,而不是像其他人建议的那样禁用 SMB 或通过注册表项进行缓存。这将允许您保持所有 Windows 设置不变,但同时不会缓存文件。

这是一个特定问题的示例: \\beta$NOCSC$\share\bug\1.txt

如果您想了解更多详情,请查看此链接:

http://blog.wisefaq.com/2016/01/26/nocscno-client-side-caching/

【讨论】:

不过,Win Server 2012 R2 好像不理解这个提示。

以上是关于Windows 文件共享:为啥有时新创建的文件在一段时间内不可见?的主要内容,如果未能解决你的问题,请参考以下文章

linux用samba共享, 为啥在windows下访问时只能看到文件夹, 而文件不可见?

微软SMB 3.0文件共享协议新特性介绍

Linux怎样访问Windows共享文件和文件夹

如何在windows8/7中建立WebDAV服务器实现访问或共享文件

linux访问windows共享文件夹的两种方法

Windows Server 2012 R2 配置域用户的配置文件