为什么FileExists不支持通配符?

Mic*_*ter 2 vbscript api-design filesystemobject

考虑这个示例VBScript片段:

Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists("D:\Folder\File*.ext") Then ' Finds nothing!
  fs.CopyFile "D:\Folder\File*.ext", "D:\OtherFolder\"
  fs.Deletefile "D:\Folder\File*.ext"
End If
Run Code Online (Sandbox Code Playgroud)

FileExists方法证明不支持通配符(*?).没有FolderExists.我预计wildards只是工作,因为他们工作的优良所有类似的方法在FileSystemObject:CopyFile,CopyFolder,MoveFile,MoveFolder,DeleteFile,DeleteFolderGet*文件名处理方法一样GetAbsolutePathName.

当然有办法解决这个问题,比如GetFolder迭代它的文件.但FileExists本来会更具可读性,方便性,自然性和一致性.

fs.FileExists不一致感觉就像一个API设计问题.可能是什么原因?背后有什么想法吗?

Tom*_*lak 5

只有设计了Microsoft Scripting Runtime API(scrrun.dll)的团队中的某些人(这些函数是其中的一部分)才能确定地回答这个问题.

但我的猜测是,FileExists不过是为一个包装CreateFile的Windows API函数dwCreationDisposition参数集OPEN_EXISTING("打开一个文件,或者只存在设备.").此Windows API函数不支持通配符,因此也不支持FileExists.

当文件不存在时,系统将响应错误2("系统找不到指定的文件.")FileExists并将返回False.

以上内容基于使用Process Monitor来检查FileExists呼叫的行为.

讨论这是否是API设计监督以及它是否应该有所不同是没有意义的.


话虽如此,没有理由在您显示的代码中进行"存在"检查.

如果要将文件从位置A移动到位置B,请执行此操作.

如果有东西要移动,它会被移动.如果没有任何动作,则可以检查错误."存在"检查不提供任何额外信息.

Dim fs, source
Set fs = CreateObject("Scripting.FileSystemObject")

On Error Resume Next

fs.MoveFile "File*.ext", "D:\OtherFolder\"

If Err.Number = 0 Then
  MsgBox "Done"
ElseIf Err.Number = 53 Then ' File not found
  MsgBox "Nothing to do"
ElseIf Err.Number = 76 Then ' Path not found
  MsgBox "Target path not found"
Else
  MsgBox "Unexpected Error " & Err.Number & " - " & Err.Description
End If

On Error Goto 0
Run Code Online (Sandbox Code Playgroud)

为了方便起见,我将其包装Sub在一起,以便我可以重复使用它,并且On Error Resume Next不会泄漏到我的其余代码中.

另外值得一提的是,在同一空间内,MoveFile将是这样快于复制和删除.

  • @MicheldeRuiter我也会推荐On Error方法,因为还有很多可能出错的内容,例如只读权限,没有权限,锁定文件,路径太长等等. (2认同)
  • 是的,但由于您的进程不是这台计算机上唯一的进程,因此在成功进行“文件存在”检查后,文件可能会在几毫秒内消失(想象一下由于某种愚蠢的原因同时运行脚本的两个实例,或者许多其他情况)。关键是,除非您保持文件句柄打开(从而防止任何人在您完成文件处理之前拿走您的文件),否则文件存在检查实际上没有任何意义。尝试您要执行的任何操作并处理错误比依赖文件存在检查并处理错误要“强大得多”。 (2认同)