Как я могу проверить правильность имени файла в Windows? - PullRequest
10 голосов
/ 20 августа 2011

Существует ли функция Windows API, в которую я могу передать строковое значение, которое будет возвращать значение, указывающее, является ли имя файла действительным или нет?

Мне нужно убедиться, что имя файла является действительным, иЯ ищу простой способ сделать это, не изобретая велосипед.Я работаю на прямом C, но нацеливаюсь на Win32 API.

Если такой встроенной функции нет, как мне написать свою собственную?Существует ли общий алгоритм или шаблон, который используется в Windows для определения достоверности имени файла?

Ответы [ 3 ]

6 голосов
/ 20 августа 2011

Проблема не так проста, поскольку она зависит от того, что вы считаете «допустимым именем файла».

API-интерфейсы Windows, используемые с путями UNC, позволят вам с радостью создать множество имен, которые считаются недействительнымивнутри обычных путей, поскольку с префиксом \\?\ вы указываете API-интерфейсам Windows просто доставить путь к драйверу файловой системы, не выполняя никакой проверки;сами файловые системы часто не заботятся о том, что они используют в качестве имени файла, поскольку они знают, что какая-то строка является только именем файла (т. е. разделение пути / имени уже выполнено), они обычно обрабатывают это как непрозрачную последовательностьсимволы.

С другой стороны, если вы хотите воспроизвести его безопасно, вы должны выполнить проверку в соответствии с правилами, указанными в документе MSDN , который вы уже связали для имен Win32;Я не думаю, что любая файловая система может иметь более строгие правила, чем эти при именовании файлов.С другой стороны, нарушение таких требований, хотя и может поддерживаться самим ядром, часто создает неприятные головные боли для многих «обычных» приложений, которые ожидают обработки «традиционных» путей Win32.

Но, на мой взгляд,, если вам нужно немедленно создать файл, лучшая проверка, которую вы можете сделать, это попытаться фактически создать / открыть файл , позволяя ОС выполнять такую ​​работу за вас, и быть готовым к корректной обработке ошибки(GetLastError должен вернуть ERROR_BAD_PATHNAME).Это проверит любые другие ограничения, которые у вас есть при создании такого файла, например, что ваше приложение имеет соответствующие разрешения, что путь находится не на носителе только для чтения, ...

Если по какой-то причине это не таквозможно, вам может понравиться функция оболочки PathCleanupSpec: при условии, что запрашиваемое имя файла и каталог в файловой системе, где он должен быть создан, эта функция удалит все недопустимые символы (я нене забывайте о зарезервированных именах DOS, они не перечислены в его документации) делая путь «вероятно допустимым» и уведомляя вас о любых изменениях (так что вы можете использовать его также только для проверки).

Обратите внимание, что этофункция помечена как «изменяемая или удаляемая в любой будущей версии Windows», хотя политика Microsoft, как правило, гласит, что «все, что попадет в публичный заголовок, останется публичным навсегда».

0 голосов
/ 20 августа 2011

Эта функция выдает список недопустимых символов для имени файла. До вас, чтобы проверить, что ваше имя файла не содержит:

public static char[] Path.GetInvalidFileNameChars()

Документы здесь .

Обратите внимание, что если вы хотите проверить имя каталога, вы должны использовать GetInvalidPathChars().

РЕДАКТИРОВАТЬ: Oooops! Извините, я думал, что вы были на .NET. Используя Reflector, эта функция сводится к следующему:

'"', '<', '>', '|', 
'\0', '\x0001', '\x0002', '\x0003', '\x0004', '\x0005', '\x0006', 
'\a', '\b', '\t', '\n', '\v', '\f', '\r', 
'\x000e', '\x000f', '\x0010', '\x0011', '\x0012', '\x0013', '\x0014', '\x0015', 
'\x0016', '\x0017', '\x0018', '\x0019', '\x001a', '\x001b', '\x001c', '\x001d', 
'\x001e', '\x001f', 
':', '*', '?', '\\', '/'

Обратите внимание, что, кроме того, существуют зарезервированные имена, такие как prn, con, com1, com2,... , lpt1, lpt2,...

0 голосов
/ 20 августа 2011

В случае, если вы проверяете, является ли имя файла действительным в смысле "может ли файл называться так?" :

Нет, функции для прямой проверки нет. Вам придется написать свою собственную функцию.

Но, если вы знаете, какое имя файла является допустимым (допустимое имя файла теперь содержит любое из следующего: \ / : * ? " < > |), это не должно быть такой проблемой.

Возможно, вы могли бы помочь себе с некоторыми из этих функций из ctype.h (с их помощью вы можете проверить, принадлежит ли определенный символ некоторым конкретным классам символов):

http://www.cplusplus.com/reference/clibrary/cctype/

...