2016-11-14 3 views
2

Рассмотрим этот пример VBScript фрагмент:Почему FileExists не поддерживает подстановочные знаки?

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. Я ожидал, что wildards просто работать, потому что они прекрасно работают для всех подобных методов в FileSystemObject: CopyFile, CopyFolder, MoveFile, MoveFolder, DeleteFile, DeleteFolder и методов обработки с Get*GetAbsolutePathName имени файла, как.

Конечно, есть способы обойти это, например GetFolder и итерацию по его файлам. Но FileExists было бы более читаемым, удобным, естественным и последовательным.

Несоответствие выглядит как проблема проектирования API. Что может быть причиной? Есть ли какая-то идея?

+0

Еще одним обходным решением может быть 'If Dir (" D: \ Folder \ File * .ext ")>" "Then' или, может быть, некоторые команды DOS – Slai

+1

@Slai' Dir' не существует в VBScript. – Tomalak

ответ

5

Только тот, кто из команды, создавшей API Runtime Microsoft Scripting (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 будет способом быстрее, чем копировать и удалять.

+2

@ MicheldeRuiter Я бы порекомендовал подход On Error, потому что есть намного больше, что может пойти не так, как разрешения только для чтения, без разрешения, заблокированные файлы, слишком длинный путь и т. Д. – Slai

+0

'FileExists' перед тем, как показать мое намерение намного лучше чем 'Err.Number = 53' после факта. Конечно, у меня есть обработка ошибок. 'CopyFile' плюс' DeleteFile' состоял только в том, чтобы показать примеры обоих. –

+1

Да, но поскольку ваш процесс не единственный на этом компьютере, файл может исчезнуть в миллисекунде после успешной проверки «файл существует» (представьте два экземпляра вашего сценария, работающего одновременно, по какой-то глупой причине, или множество других ситуаций). Дело в том, что, если вы не держите дескриптор файла открытым (и, таким образом, не позволяете никому отбирать файл, прежде чем вы его завершите), проверка наличия файла действительно ничего не значит. Это * много * более надежный, чтобы попробовать любую операцию, которую вы собираетесь делать, и обрабатывать ошибки, чем полагаться на файл, проверить и не обрабатывать ошибки. – Tomalak

Смежные вопросы