Я хочу включить функцию переименования командного файла в мое приложение. Пользователь может ввести шаблон имени файла назначения и (после замены некоторых шаблонов в шаблоне) мне нужно проверить, будет ли это допустимое имя файла в Windows. Я пытался использовать регулярное выражение, как, [a-zA-Z0-9_]+
но оно не включает в себя много национальных символов из разных языков (например, умляуты и так далее). Каков наилучший способ сделать такую проверку?
c#
windows
file
filesystems
Томаша
источник
источник
Ответы:
Вы можете получить список недопустимых символов из
Path.GetInvalidPathChars
иGetInvalidFileNameChars
.UPD: см . Предложение Стива Купера о том, как использовать их в регулярном выражении.
UPD2: обратите внимание, что в соответствии с разделом «Примечания» в MSDN «Массив, возвращаемый этим методом, не обязательно содержит полный набор символов, недопустимых в именах файлов и каталогов». Ответ, предоставленный Sixlettervaliables, входит в более подробную информацию.
источник
В MSDN «Наименование файла или каталога» приведены общие соглашения о том, что такое допустимое имя файла под Windows:
Вы можете использовать любой символ в текущей кодовой странице (Unicode / ANSI выше 127), кроме:
<
>
:
"
/
\
|
?
*
Некоторые дополнительные вещи, чтобы проверить:
\?\
префикса)\?\
(обратите внимание, что префикс может расширять компоненты каталога и приводить к переполнению лимита в 32 000)источник
Regex unspupportedRegex = new Regex("(^(PRN|AUX|NUL|CON|COM[1-9]|LPT[1-9]|(\\.+)$)(\\..*)?$)|(([\\x00-\\x1f\\\\?*:\";|/<>])+)|(([\\. ]+)", RegexOptions.IgnoreCase);
^(?!^(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)(?:\.*?(?!\.))[^\x00-\x1f\\?*:\";|\/<>]+(?<![\s.])$
Для .Net Framework до 3.5 это должно работать:
Соответствие регулярных выражений поможет вам в этом. Вот фрагмент, использующий
System.IO.Path.InvalidPathChars
константу;Для .Net Frameworks после 3.0 это должно работать:
http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars(v=vs.90).aspx
Соответствие регулярных выражений поможет вам в этом. Вот фрагмент, использующий
System.IO.Path.GetInvalidPathChars()
константу;После того, как вы это узнаете, вы должны также проверить различные форматы, например,
c:\my\drive
и\\server\share\dir\file.ext
источник
Попытайтесь использовать это, и ловите для ошибки. Разрешенный набор может меняться в разных файловых системах или в разных версиях Windows. Другими словами, если вы хотите знать, нравится ли Windows имя, передайте ему имя и дайте ему сказать.
источник
Этот класс очищает имена файлов и пути; используйте это как
Вот код;
источник
Это то, что я использую:
Первый шаблон создает регулярное выражение, содержащее недопустимые / недопустимые имена файлов и символы только для платформ Windows. Второй делает то же самое, но гарантирует, что имя является законным для любой платформы.
источник
@"^(?!(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)[^\x00-\x1F\xA5\\?*:\"";|\/<>]+(?<![\s.])$"
Нужно помнить один угловой случай, который удивил меня, когда я впервые узнал об этом: Windows позволяет вводить пробелы в именах файлов! Например, ниже приведены все допустимые и разные имена файлов в Windows (без кавычек):
Один из выводов из этого: будьте осторожны при написании кода, который удаляет начальные / конечные пробелы из строки имени файла.
источник
Упрощение ответа Евгения Каца:
Или
источник
Path.GetInvalidFileNameChars
. Посмотрите здесь: referenceource.microsoft.com/#mscorlib/system/io/path.cs,289 - для каждого вашего символаfileName
создается клон массива.Microsoft Windows: ядро Windows запрещает использование символов в диапазоне 1-31 (т. Е. 0x01-0x1F) и символов "*: <>? \ |. Хотя NTFS позволяет каждому компоненту пути (каталогу или имени файла) иметь длину 255 символов и длина путей до 32767 символов, ядро Windows поддерживает только пути длиной до 259. Кроме того, Windows запрещает использование имен устройств MS-DOS AUX, CLOCK $, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, CON, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, NUL и PRN, а также эти имена с любым расширением (например, AUX.txt), кроме случаев использования Длинные UNC-пути (например, \. \ C: \ nul.txt или \? \ D: \ aux \ con). (Фактически, CLOCK $ может использоваться, если предоставляется расширение.) Эти ограничения применяются только к Windows - Linux, например, позволяет использовать "*: <>? \ | даже в NTFS.
Источник: http://en.wikipedia.org/wiki/Filename
источник
Вместо того, чтобы явно включать все возможные символы, вы можете выполнить регулярное выражение, чтобы проверить наличие недопустимых символов, и затем сообщить об ошибке. В идеале ваше приложение должно называть файлы в точности так, как пожелает пользователь, и кричать нечестно, только если наткнется на ошибку.
источник
Вопрос в том, пытаетесь ли вы определить, является ли имя пути допустимым путем окон или оно разрешено в системе, где выполняется код. ? Я думаю, что последнее более важно, поэтому лично я, вероятно, разложил бы полный путь и попытался бы использовать _mkdir для создания каталога, к которому принадлежит файл, а затем попытаться создать файл.
Таким образом, вы знаете не только, содержит ли путь только допустимые символы Windows, но и действительно ли он представляет путь, который может быть записан этим процессом.
источник
Я использую это, чтобы избавиться от недопустимых символов в именах файлов без исключения:
источник
Также CON, PRN, AUX, NUL, COM # и некоторые другие никогда не являются допустимыми именами файлов в любом каталоге с любым расширением.
источник
Чтобы дополнить другие ответы, вот пара дополнительных крайних случаев, которые вы можете рассмотреть.
В Excel могут возникнуть проблемы, если вы сохраните книгу в файл, имя которого содержит символы «[» или «]». См. Http://support.microsoft.com/kb/215205 для получения подробной информации.
Sharepoint имеет целый дополнительный набор ограничений. См. Http://support.microsoft.com/kb/905231 для получения подробной информации.
источник
Из MSDN , вот список символов, которые не допускаются:
источник
Также важна файловая система назначения.
Под NTFS некоторые файлы не могут быть созданы в определенных каталогах. EG $ загрузка в корне
источник
$Boot
уже существует в каталоге?Это вопрос, на который уже дан ответ, но просто ради «других вариантов», вот неидеальный:
(неидеально, потому что использование исключений в качестве управления потоком, как правило, является «плохой вещью»)
источник
true
.Регулярные выражения излишни для этой ситуации. Вы можете использовать
String.IndexOfAny()
метод в сочетании сPath.GetInvalidPathChars()
иPath.GetInvalidFileNameChars()
.Также обратите внимание, что оба
Path.GetInvalidXXX()
метода клонируют внутренний массив и возвращают клон. Поэтому, если вы собираетесь делать это много раз (тысячи и тысячи раз), вы можете кэшировать копию недопустимого массива chars для повторного использования.источник
Если вы пытаетесь проверить, не содержит ли строка, содержащая ваше имя / путь к файлу, недопустимые символы, самый быстрый способ, который я нашел, - это использовать
Split()
для разбиения имени файла на массив частей, где есть недопустимый символ. Если результатом является только массив 1, недопустимые символы отсутствуют. :-)Я попытался запустить этот и другие методы, упомянутые выше, для имени файла / пути 1 000 000 раз в LinqPad.
Использование
Split()
составляет всего ~ 850 мс.Использование
Regex("[" + Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]")
составляет около 6 секунд.Более сложные регулярные выражения справляются НАМНОГО хуже, как и некоторые другие опции, такие как использование различных методов
Path
класса для получения имени файла и выполнения их внутренней проверки (скорее всего из-за накладных расходов на обработку исключений).Конечно, не очень часто нужно проверять 1 миллион имен файлов, так что в любом случае для большинства этих методов подходит одна итерация. Но это все еще довольно эффективно и эффективно, если вы ищете только недопустимые символы.
источник
многие из этих ответов не будут работать, если имя файла слишком длинное и работает в среде, предшествующей Windows 10. Точно так же подумайте о том, что вы хотите делать с периодами - разрешить начальное или конечное значение технически допустимо, но это может создать проблемы, если вы не хотите, чтобы файл трудно было увидеть или удалить соответственно.
Это атрибут проверки, который я создал для проверки правильности имени файла.
и тесты
источник
Моя попытка:
Это не идеально, потому
Path.GetInvalidPathChars
что не возвращает полный набор символов, которые недопустимы в именах файлов и каталогов, и, конечно, есть еще много тонкостей.Поэтому я использую этот метод в качестве дополнения:
Он пытается создать файл и вернуть false, если есть исключение. Конечно, мне нужно создать файл, но я думаю, что это самый безопасный способ сделать это. Также обратите внимание, что я не удаляю созданные каталоги.
Вы также можете использовать первый метод для базовой проверки, а затем тщательно обрабатывать исключения, когда используется путь.
источник
Я предлагаю просто использовать Path.GetFullPath ()
источник
Я получил эту идею от кого-то. - не знаю кто. Пусть ОС сделает тяжелую работу.
источник
Эта проверка
отфильтровывает имена с недействительными символами (
<>:"/\|?*
и ASCII 0-31), а также зарезервированными устройствами DOS (CON
,NUL
,COMx
). Это позволяет начальные пробелы и все-точечные имена, в соответствии сPath.GetFullPath
. (Создание файла с начальными пробелами успешно в моей системе).Используется .NET Framework 4.7.1, протестировано на Windows 7.
источник
Один лайнер для проверки нелегальных символов в строке:
источник
На мой взгляд, единственный правильный ответ на этот вопрос - попытаться использовать путь и позволить ОС и файловой системе его проверить. В противном случае вы просто реализуете (и, вероятно, плохо) все правила проверки, которые ОС и файловая система уже используют, и если эти правила будут изменены в будущем, вам придется изменить свой код, чтобы он соответствовал им.
источник
Имена файлов Windows , довольно unrestrictive, поэтому на самом деле это не может быть даже , что большая часть проблемы. Символы, которые запрещены Windows:
Вы можете легко написать выражение, чтобы проверить, присутствуют ли эти символы. Тем не менее, лучшим решением было бы попытаться назвать файлы так, как хочет пользователь, и предупредить их, когда имя файла не совпадает.
источник