Windows文件共享:为什么有时新创建的文件不是';有一段时间看不见吗?

Windows文件共享:为什么有时新创建的文件不是';有一段时间看不见吗?,windows,share,smb,Windows,Share,Smb,我们面临着非常奇怪的问题,这让我们发疯。有时,我们的文件共享PC上新创建的文件在一段时间内“不存在”。要重现一个问题,您应该至少有两台计算机,称它们为alpha和beta。在betaPC(\\beta\share\bug)上创建文件共享,并从alphaPC运行此PowerShell脚本: param( $sharePath="\\beta\share\bug" ) $sharePC = ($sharePath -split '\\')[2] $session = New-PSSession

我们面临着非常奇怪的问题,这让我们发疯。有时,我们的文件共享PC上新创建的文件在一段时间内“不存在”。要重现一个问题,您应该至少有两台计算机,称它们为
alpha
beta
。在
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
...
!!! File \\beta\share\bug\3.txt does NOT exist!
!!! File \\beta\share\bug\4.txt does NOT exist!
现在: 打开
cmd.exe
并运行以下命令:

如果存在\\beta\share\bug\foo.txt echo 1

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

File \\beta\share\bug\1.txt exists
File \\beta\share\bug\2.txt exists
...
!!! File \\beta\share\bug\3.txt does NOT exist!
!!! File \\beta\share\bug\4.txt does NOT exist!
我们发现这个错误是由枚举创建新文件的共享目录引起的。在
Python
中,调用
os.listdir('//beta/share/bug')
来重现一个bug。在
C
中:
目录.GetDirectories(@“\\beta\share\bug”)
。您甚至可以通过shell导航到共享目录并调用
ls
dir

在Windows Server 2008 R2上发现错误

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

我们目前有两种解决此问题的方法:

  • 若客户端看到这种情况,它会在有问题的目录中创建一些临时文件——在这些文件神奇地出现之后
  • 禁用SMB 2.0:
  • 有没有人发现过类似的问题,并能解释为什么会发生,以及如何“正确地解决”它


    谢谢

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

    因此,我们继续使用“
    禁用SMB 2.0
    ”解决方案。至少它起作用了


    我遇到了类似的问题,最终找到了问题的原因。具体问题是SMB2目录缓存,它是:

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

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

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


    我认为整个问题在Windows2008R2/7及更高版本中已得到修复,但我无法绝对证实。这在现代版本的Windows中仍然是一个问题。有关详细信息,请参阅下面的注释。

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


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


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

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

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

    如果需要更多详细信息,请选中此链接:


    你看过网络跟踪以了解发生了什么吗?没有,不幸的是,我没有看过网络跟踪。我不认为网络跟踪会有所帮助。这似乎是服务器端的缓存问题。从Windows 2003到2012R2,我们遇到了完全相同的问题。SMB似乎显示了创建这些文件的服务器的文件,但随后向查询这些文件的其他服务器显示了这些文件尚不存在。这很糟糕。它在2008R2及更高版本中没有固定。事实上,这在Windows 2012R2中仍然是一个问题。顺便说一下,此解决方案解决了通过SMB共享访问Windows 2012R2的计算机的问题。谢谢你,贾斯汀,你在这里的信息非常有价值@Brain2000感谢您确认这在以后的版本中仍然是一个问题。我仍然发现这在Windows 8.1中是一个问题。最近在Windows 10中开始出现这个问题。这为meLudicrous解决了这个问题,听起来,这对我来说是最简单的答案(我是作为一个用户浏览的,不是自动的),但是,似乎不是