问题
Consider this example VBScript fragment:
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
The FileExists method turns out not to support wildcards (*
and ?
). Not does FolderExists. I expected wildards to just work because they work fine for all similar methods in the FileSystemObject: CopyFile, CopyFolder, MoveFile, MoveFolder, DeleteFile, DeleteFolder and the Get*
filename handling methods like GetAbsolutePathName.
Of course there are ways to work around this, like GetFolder and iterating over its files. But FileExists
would have been much more readable, convenient, natural and consistent.
The fs.FileExists
inconsistency feels like an API design problem. What could be the reason? Is there some idea behind it?
回答1:
Only someone from the team that designed the Microsoft Scripting Runtime API (scrrun.dll), which these functions are a part of, can answer this question for sure.
But my guess is that FileExists
is nothing but a wrapper for the CreateFile Windows API function with the dwCreationDisposition
parameter set to OPEN_EXISTING
("Opens a file or device only if it exists."). This Windows API function does not support wildcards, so FileExists
can't, either.
When the file does not exist, the system will respond with error 2 ("The system cannot find the file specified.") and FileExists
will return False
.
The above is based on using Process Monitor to inspect the behavior of a FileExists
call.
It would be moot to discuss whether this is an API design oversight and whether it should be any different.
That being said, there is no reason for an "exists" check in the code you show.
If you want to move files from location A to location B, just do that.
If there is something to move, it will be moved. If there is nothing to move, there will be an error you can inspect. The "exists" check provides no extra information whatsoever.
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
For convenience I would wrap that in a Sub
so that I can re-use it and the On Error Resume Next
won't leak into the rest of my code.
It's also worth noting that within the same volume, MoveFile
will be way faster than copy-and-delete.
来源:https://stackoverflow.com/questions/40585712/why-doesnt-fileexists-support-wildcards