Windows 文件共享:为什么有时新创建的文件在一段时间内不可见?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5159220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Windows file share: why sometimes newly created files aren't visible for some period of time?
提问by Roman
We were faced with very strange issue that made us crazy. Sometimes newly created files on our File Share PC were "absent" for some period of time. To reproduce a problem you should have at least two computers, call them alpha
and beta
. Create file share on beta
PC (\\beta\share\bug
) and run this PowerShell script from alpha
PC:
我们面临着让我们发疯的非常奇怪的问题。有时,我们的文件共享 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
}
After starting this script you should be able to see these messages:
启动此脚本后,您应该能够看到以下消息:
File \beta\share\bug.txt exists
File \beta\share\bug.txt exists
...
And now:
Open cmd.exe
and run this command:
现在:打开cmd.exe
并运行此命令:
if exist \\beta\share\bug\foo.txt echo 1
if exist \\beta\share\bug\foo.txt echo 1
After this during approx 10 seconds you'll see following messages:
大约 10 秒后,您将看到以下消息:
!!! File \beta\share\bug.txt does NOT exist!
!!! File \beta\share\bug.txt does NOT exist!
We've discovered that bug is caused by enumerating shared directory where new files are being created. In Python
call os.listdir('//beta/share/bug')
to reproduce a bug. In C#
: Directory.GetDirectories(@"\\beta\share\bug")
. You can even simply navigate to share directory by shell and call ls
or dir
.
我们发现该错误是由枚举正在创建新文件的共享目录引起的。在Python
调用os.listdir('//beta/share/bug')
中重现错误。在C#
:Directory.GetDirectories(@"\\beta\share\bug")
。您甚至可以简单地通过 shell 导航到共享目录并调用ls
或dir
。
Bug were found on Windows Server 2008 R2
发现错误 Windows Server 2008 R2
Note, that you cannot watch directory content on alpha
PC in Windows Explorer in real time, because if you open this directory in Explorer bug would not occur! So ensure to close all such windows before attempts to reproduce a bug. After each script restart you should manually remove all already created files from share (because script is rather stupid and always starts from 0.txt).
请注意,您无法alpha
在 Windows 资源管理器中实时查看PC上的目录内容,因为如果您在资源管理器中打开此目录,则不会发生错误!因此,请确保在尝试重现错误之前关闭所有此类窗口。每次脚本重新启动后,您应该手动从共享中删除所有已创建的文件(因为脚本相当愚蠢并且总是从 0.txt 开始)。
We currently have 2 workarounds for this issue:
对于这个问题,我们目前有两种解决方法:
- If client sees this situation, it creates some temporary file in problematic directory - after this files magically appear.
- Disable SMB 2.0: http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm
- 如果客户端看到这种情况,它会在有问题的目录中创建一些临时文件 - 在这些文件神奇地出现之后。
- 禁用 SMB 2.0:http: //www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm
Does anybody have ever discovered similar problem and can explain why it occurs and how "correctly fix" it?
有没有人发现过类似的问题并且可以解释它为什么会发生以及如何“正确修复”它?
Thanks
谢谢
回答by Justin Michael
I was experiencing a similar problem and, eventually, I found the cause of this issue. The specific problem is the SMB2 Directory Cache, which is one of the SMB2 Client Redirector cache components:
我遇到了类似的问题,最终我找到了这个问题的原因。具体问题是 SMB2 目录缓存,它是SMB2 客户端重定向器缓存组件之一:
This is a cache of recent directory enumerations performed by the client. Subsequent enumeration requests made by client applications as well as metadata queries for files in the directory can be satisfied from the cache. The client also uses the directory cache to determine the presence or absence of a file in the directory and uses that information to prevent clients from repeatedly attempting to open files which are known not to exist on the server. This cache is likely to affect distributed applications running on multiple computers accessing a set of files on a server – where the applications use an out of band mechanism to signal each other about modification/addition/deletion of files on the server.
这是客户端执行的最近目录枚举的缓存。客户端应用程序发出的后续枚举请求以及目录中文件的元数据查询可以从缓存中得到满足。客户端还使用目录缓存来确定目录中是否存在文件,并使用该信息来防止客户端重复尝试打开服务器上已知不存在的文件。此缓存可能会影响在多台计算机上运行的分布式应用程序访问服务器上的一组文件 - 其中应用程序使用带外机制相互发送有关服务器上文件的修改/添加/删除的信号。
The default value for this wonderful little cache is 10 seconds, which is producing the behavior you're seeing. When your code asks the system about that directory/file it's getting the cached result, which is 10 seconds old, so it says the file does not exist. Setting HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime
(DWORD) to a value of 0
will disable the cache and resolve the file doesn't exist issue. Surprisingly this change does notrequire a restart of the client machine! This will also allow you to keep SMB2 enabled, which should be better for a number of reasons vs. forcing SMB1.
这个美妙的小缓存的默认值是 10 秒,这会产生您所看到的行为。当您的代码向系统询问该目录/文件时,它会得到缓存结果,这是 10 秒前的结果,因此它说该文件不存在。将HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime
(DWORD) 设置为值0
将禁用缓存并解决文件不存在的问题。令人惊讶的这一变化并没有要求在客户机重新启动!这也将允许您保持 SMB2 启用,出于多种原因,这应该比强制 SMB1 更好。
Furthermore, the cache is not used when the share in question is opened in Windows explorer, as having it open tells the system to bypass the cache to keep a live view going. Modifying something in the share via code, however, does not.
此外,当在 Windows 资源管理器中打开有问题的共享时,不会使用缓存,因为打开它会告诉系统绕过缓存以保持实时取景。但是,通过代码修改共享中的某些内容不会。
I think this whole issue is fixed in Windows 2008 R2/7 and higher, but I cannot absolutely confirm it.This is still an issue in modern versions of Windows. See the comments below for details.
我认为这整个问题已在 Windows 2008 R2/7 及更高版本中得到解决,但我不能完全确认。这在现代版本的 Windows 中仍然是一个问题。有关详细信息,请参阅下面的评论。
回答by Roman
A month passed and no answer...
一个月过去了,没有任何回应……
So, we stayed with "Disable SMB 2.0
" solution. At least it works.
所以,我们仍然使用“ Disable SMB 2.0
”解决方案。至少它有效。
http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm
http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm
回答by user281806
There is also a bug in Windows 7 SP1 for which there is a hotfix available
Windows 7 SP1 中还有一个错误,有可用的修补程序
用户添加到远程文件夹的文件不会显示在运行 Windows 7 或 Windows Server 2008 R2 的计算机上的 Windows 资源管理器中
回答by zmechanic
You can use magical suffix $NOCSC$
, instead of disabling SMB or caching via registry keys, as some others suggested. This will allow you to leave all Windows settings intact, but at the same time files will not get cached.
您可以使用神奇的 suffix $NOCSC$
,而不是像其他人建议的那样通过注册表项禁用 SMB 或缓存。这将允许您保留所有 Windows 设置不变,但同时文件不会被缓存。
Here is a question specific example:
\\beta$NOCSC$\share\bug\1.txt
这是一个特定于问题的示例:
\\beta$NOCSC$\share\bug\1.txt
Check this link if you want more details:
如果您想了解更多详情,请查看此链接:
http://blog.wisefaq.com/2016/01/26/nocscno-client-side-caching/
http://blog.wisefaq.com/2016/01/26/nocscno-client-side-caching/
回答by Michel de Ruiter
The easiest way to work around this (as suggested by the OP) is to create a temporary file or subfolder in the folder where you expect the files to appear and remove it right away. This triggers the change to become visible.
解决此问题的最简单方法(如 OP 所建议的)是在您希望文件出现的文件夹中创建一个临时文件或子文件夹,然后立即将其删除。这会触发更改变得可见。
We noticed that having a FileSystemWatcher
in the folder also helps, even when it does nothing.
我们注意到FileSystemWatcher
文件夹中有 a也有帮助,即使它什么都不做。