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

我们面对非常奇怪的问题,使我们疯了。 有时我们的文件共享PC上新创build的文件在一段时间内“缺席”。 重现一个问题,你至less应该有两台电脑,称之为alphabeta 。 在beta PC上创build文件共享( \\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! 

我们发现这个错误是由枚举创build新文件的共享目录造成的。 在Python调用os.listdir('//beta/share/bug')来重现一个bug。 在C#Directory.GetDirectories(@"\\beta\share\bug") 。 你甚至可以简单地导航到shell共享目录,并调用lsdir

Windows Server 2008 R2上发现了错误

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

我们目前对这个问题有两个解决方法:

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

有没有人发现类似的问题,可以解释为什么会发生,以及如何“正确地解决”?

谢谢

我遇到了类似的问题,最终我发现了这个问题的原因。 具体的问题是SMB2目录缓存,它是SMB2客户端重定向缓存组件之一 :

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

这个美妙的小缓存的默认值是10秒,这是产生你所看到的行为。 当你的代码向系统询问这个目录/文件时,它会得到缓存的结果,这个结果是10秒钟,所以它说文件不存在。 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime (DWORD)值设置为0将禁用缓存并解决文件不存在的问题。 令人惊讶的是,这种改变不需要重新启动客户机! 这也可以让你保持启用SMB2,这应该是更好的一些原因与强制SMB1。

而且,在Windows资源管理器中打开共享时,不会使用缓存,因为打开它会告诉系统绕过缓存以保持实时视图的运行。 但是,通过代码修改共享中的内容不会。

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

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

所以,我们留下了“ Disable SMB 2.0 ”解决方案。 至少它工作。

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

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

用户添加到远程文件夹的文件不会显示在运行Windows 7或Windows server 2008 R2的计算机上的Windows资源管理器中

解决此问题的最简单方法(如OP所建议的)是在希望文件出现的文件夹中创建临时文件或子文件夹,并立即将其删除。 这触发了变化变得可见。

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

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

这里是一个问题的具体例子: \\beta$NOCSC$\share\bug\1.txt

检查这个链接,如果你想要更多的细节:

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