为什么FileExists不支持通配符?

时间:2016-11-14 09:43:11

标签: 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

FileExists方法证明不支持通配符(*?)。不是FolderExists。我希望通配符可以正常工作,因为它们适用于FileSystemObject中的所有类似方法:CopyFileCopyFolderMoveFileMoveFolder,{{3} },DeleteFileGet*文件名处理方法,例如DeleteFolder

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

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

2 个答案:

答案 0 :(得分:5)

只有那些设计了Microsoft Scripting Runtime API(scrrun.dll)的团队中的某些人才能回答这个问题。

但我的猜测是FileExists只是CreateFile Windows API function的包装,而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

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

同样值得注意的是,在同一卷中,MoveFile 方式比复制和删除更快。

答案 1 :(得分:-1)

为什么不通过 WSShell.Exec 运行 DIR 并捕获其输出?

set ows=createobject("Wscript.shell")
path="C:\windows\system32\"
wild="*.exe"
recurse="/S"  ' or ""
Set oExec=ows.Exec("%comspec% /c dir /b " & recurse &" "& chr(34) & path & wild & chr(34) )
s= oExec.StdOut.ReadAll()

'using the result
if s =vbnullstring then
   Wscript.echo "No files found" 
else
   s=split(s,vbcrlf) 
   wscript.echo "Files found " & ubound(s)
   for each i in s
      wscript.echo i
   next
   wscript.echo "End of list"
end if