Какие символы запрещены в именах каталогов Windows и Linux?

253

Я знаю, что/является незаконным в Linux, а следующие недопустимы в Windows (Я думаю) * . " / \ [ ] : ; | = ,

Что еще мне не хватает?

Мне нужно всестороннее руководство, и оно учитывает двухбайтовые символы. Ссылка на внешние ресурсы в порядке со мной.

Мне нужно сначала создать каталог в файловой системе, используя имя, которое может содержат запрещенные символы, поэтому я планирую заменить эти символы на подчеркивания. Затем мне нужно записать этот каталог и его содержимое в zip файл (с использованием Java), поэтому любой дополнительный совет, касающийся имен zip-каталогов будет оценено.

  • 8
    Некоторые персонажи, о которых вы упоминаете, на самом деле разрешены в Windows. Проверьте это: echo abc > "ab.;,=[1]"
  • 0
    Возможно, вы захотите использовать encodeURIComponent (Javascript) или эквивалентный.
Показать ещё 8 комментариев
Теги:
directory
filenames
zip

12 ответов

183
Лучший ответ

"Полное руководство" запрещенных имен файлов не будет работать в Windows, поскольку оно хранит имена файлов, а также символы. Да, персонажи вроде * " ?, а другие запрещены, но существует бесконечное количество имен, состоящих только из допустимых символов, которые запрещены. Например, пробелы и точки являются действительными именами имен файлов, но имена, состоящие только из этих символов, запрещены.

В Windows не проводится различие между строчными и строчными символами, поэтому вы не можете создать папку с именем A, если один из них с именем A уже существует. Хуже, по-видимому, такие имена, как PRN и CON, и многие другие, зарезервированы и не разрешены. Windows также имеет несколько ограничений длины; имя файла, действительное в одной папке, может стать недействительным, если оно перемещено в другую папку. Правила для именование файлов и папок находится на MSDN.

Вы не можете, в общем, использовать созданный пользователем текст для создания имен каталога Windows. Если вы хотите, чтобы пользователи написали что-либо, что они хотят, вы должны создать безопасные имена, такие как A, AB, A2 и др., Хранить созданные пользователем имена и их эквиваленты путей в файле данных приложения и выполните сопоставление маршрутов в вашем приложении.

Если вы абсолютно должны разрешать имена файлов, созданных пользователем, единственный способ определить, являются ли они недопустимыми, - это исключить исключения и предположить, что имя недействительно. Даже это чревато опасностью, поскольку исключения, запрещенные для доступа, автономные диски и из пространства на диске, перекрываются с теми, которые могут быть выбраны для недопустимых имен. Вы открываете одну огромную баню с болью.

  • 6
    Отличный момент. Если бы я только вспомнил, что означает COPY CON ...
  • 8
    Ключевая фраза из ссылки MSDN - «[и] любой другой символ, который целевая файловая система не разрешает». В Windows могут быть разные файловые системы. Некоторые могут разрешить Unicode, другие - нет. В общем, единственный безопасный способ проверить имя - это попробовать его на целевом устройстве.
Показать ещё 7 комментариев
340

Пусть будет проще и ответь сначала на вопрос.

  1. Запрещенные печатные символы ASCII:

    • Linux/Unix:

      / (forward slash)
      
    • Окна:

      < (less than)
      > (greater than)
      : (colon - sometimes works, but is actually NTFS Alternate Data Streams)
      " (double quote)
      / (forward slash)
      \ (backslash)
      | (vertical bar or pipe)
      ? (question mark)
      * (asterisk)
      
  2. Непечатные символы

    Если ваши данные поступают из источника, который разрешает непечатные символы, есть еще что проверить.

    • Linux/Unix:

      0 (NULL byte)
      
    • Окна:

      0-31 (ASCII control characters)
      

    Примечание. Хотя в файловых системах Linux/Unix разрешено создавать файлы с управляющими символами в имени файла, пользователям может показаться кошмарным иметь дело с такими файлами.

  3. Зарезервированные имена файлов

    Следующие имена файлов зарезервированы:

    • Окна:

      CON, PRN, AUX, NUL 
      COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
      LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9
      

      (как самостоятельно, так и с произвольными расширениями файлов, например LPT1.txt).

  4. Другие правила

    • Окна:

      Имена файлов не могут заканчиваться пробелом или точкой.

  • 3
    Большинство файловых систем Windows не ограничены 8-битными символами. Есть много других 8-битных символов (NUL, управляющие символы), которые запрещены в Windows. Даже рассмотрение этих вопросов не позволит спрашивающему «создать каталог в файловой системе», как он спросил, потому что существует бесконечное количество недопустимых имен каталогов, состоящих из незапрещенных символов.
  • 27
    Другие уже говорили это, и это не конструктивно. Когда я пришел сюда в поисках ответа, мне понадобился список, который я должен был собрать в другом месте: какие символы отфильтровывать из пользовательского ввода при создании удачной попытки ввести правильное имя файла. Вопрос, если символы вместе становятся недействительными, также может потребовать некоторой проработки.
Показать ещё 17 комментариев
56

В Linux и других Unix-системах есть только два символа, которые не могут появляться в имени файла или каталога, и это NUL '\0' и косая черта '/'. Разумеется, косая черта может появляться в имени пути, разделяющем компоненты каталога.

Слух 1 гласит, что Стивен Борн (из "оболочки" известность) был каталог, содержащий 254 файлов, по одному для каждой буквы (код символа), который может появиться в имени файла ( за исключением /, '\0', имя . Было текущий каталог, конечно). Он использовался для тестирования оболочки Bourne и регулярно наносил ущерб неосторожным программам, таким как программы резервного копирования.

Другие люди рассмотрели правила Windows.

Обратите внимание, что MacOS X имеет регистронезависимую файловую систему.


1 Керниган и Пайк из "Практики программирования" так и сказали в главе 6 "Тестирование", §6.5 Стресс-тесты:

Когда Стив Борн писал свою оболочку Unix (известную как оболочка Борна), он создал каталог из 254 файлов с односимвольными именами, по одному на каждое значение байта, кроме '\0' и косой черты, двух символов, которые не может появиться в именах файлов Unix. Он использовал этот каталог для всевозможных тестов сопоставления с образцом и токенизации. (Тестовый каталог, конечно, был создан программой.) В течение многих лет этот каталог был бичем программ для обхода файловых деревьев; это проверило их на разрушение.

  • 1
    254 файла? А что насчет utf8?
  • 16
    Все 254 файла представляли собой односимвольные имена файлов, по одному на символ, что было разрешено в имени файла. UTF-8 не был даже проблеском в глазах, когда Стив Борн написал оболочку Борна. UTF-8 налагает правила относительно допустимых последовательностей байтов (и запрещает байты 0xC0, 0xC1, 0xF5-0xFF в целом). В остальном, это не сильно отличается - на уровне деталей, которые я обсуждаю.
Показать ещё 4 комментария
28

Вместо того, чтобы создавать черный список символов, вы можете использовать белый список. Учитывая все это, диапазон символов, которые имеют смысл в контексте имен файлов или каталогов, довольно мал, и если у вас нет особых требований к именованию, ваши пользователи не будут применять его к вашему приложению, если они не смогут использовать всю таблицу ASCII.

Это не решает проблему зарезервированных имен в целевой файловой системе, но с белым списком легче снизить риски в источнике.

В этом духе это ряд символов, которые можно считать безопасными:

  • Буквы (az AZ) - также символы Unicode, если это необходимо
  • Цифры (0-9)
  • Нижнее подчеркивание (_)
  • Дефис (-)
  • Космос
  • Точка (.)

И любые дополнительные безопасные символы, которые вы хотите разрешить. Помимо этого, вам просто нужно применить некоторые дополнительные правила, касающиеся пробелов и точек. Обычно этого достаточно:

  • Имя должно содержать хотя бы одну букву или цифру (чтобы избежать только точек/пробелов)
  • Имя должно начинаться с буквы или цифры (чтобы избежать начальных точек/пробелов)
  • Имя не может заканчиваться точкой или пробелом (просто обрезать их, если они есть, как в Проводнике)

Это уже позволяет довольно сложные и бессмысленные имена. Например, эти имена будут возможны с этими правилами, и будут действительными именами файлов в Windows/Linux:

  • A...........ext
  • B -.-.ext

По сути, даже с таким количеством символов в белом списке вы все равно должны решить, что на самом деле имеет смысл, и соответствующим образом проверить/скорректировать имя. В одном из моих приложений я использовал те же правила, что и выше, но удалил все дублирующие точки и пробелы.

  • 6
    А как насчет моих не говорящих по-английски пользователей, которые бы все облажались?
  • 1
    @pkh: Как я уже упоминал в своем посте, вы должны включить в свой белый список любые необходимые символы Юникода. Диапазоны символов обычно можно указать довольно легко, особенно если вы используете, например, регулярные выражения.
Показать ещё 5 комментариев
24

Хорошо, если только в исследовательских целях, то лучше всего посмотреть на эту запись в Википедии по именам файлов.

Если вы хотите написать портативную функцию для проверки ввода пользователя и создания имен файлов на основе этого, короткий ответ не. Взгляните на переносимый модуль, например Perl File:: Spec, чтобы взглянуть на все прыжки, необходимые для выполнения такой "простой" задачи.

22

Легкий способ заставить Windows сказать вам ответ - попытаться переименовать файл через Explorer и ввести/для нового имени. В Windows появится окно с сообщением о списке недопустимых символов.

A filename cannot contain any of the following characters:
    \ / : * ? " < > | 

https://support.microsoft.com/en-us/kb/177506

5

Для Windows вы можете проверить его с помощью PowerShell

$PathInvalidChars = [System.IO.Path]::GetInvalidPathChars() #36 chars

Для отображения кодов UTF-8 вы можете конвертировать

$enc = [system.Text.Encoding]::UTF8
$PathInvalidChars | foreach { $enc.GetBytes($_) }

$FileNameInvalidChars = [System.IO.Path]::GetInvalidFileNameChars() #41 chars

$FileOnlyInvalidChars = @(':', '*', '?', '\', '/') #5 chars - as a difference
1

По состоянию на 18/04/2017 среди простых ответов на эту тему нет простого черного или белого списка символов и имен файлов - и ответов много.

Лучшее предложение, которое я мог придумать, состояло в том, чтобы позволить пользователю называть файл так, как ему нравится. Используя обработчик ошибок, когда приложение пытается сохранить файл, перехватите все исключения, предположите, что виновато имя файла (очевидно, после того, как убедитесь, что путь сохранения тоже был в порядке), и запросите у пользователя новое имя файла. Для достижения наилучших результатов поместите эту процедуру проверки в цикл, который продолжается до тех пор, пока пользователь не поймет это правильно или не сдастся. Лучше всего сработало для меня (по крайней мере, в VBA).

  • 0
    Ваш ответ @FCastro правильный с технической точки зрения. Однако с точки зрения UX это кошмар - пользователь вынужден играть в игру типа «набери что-нибудь, и я скажу тебе, если у тебя получится» снова и снова. Я бы предпочел увидеть сообщение (стиль предупреждения), сообщающее пользователю, что он ввел недопустимый символ, который позже будет преобразован.
  • 0
    Кристофер Оезбек представил такой черный список в 2015 году.
0

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

  • 0
    «не ответ ... отказался - модератор проверил ваш флаг, но не нашел никаких доказательств в его поддержку». Ты меня разыгрываешь. Лучше модераторы, пожалуйста.
0

В оболочках Unix вы можете цитировать почти каждый символ в одинарных кавычках '. Кроме самой одиночной кавычки, и вы не можете выразить управляющие символы, потому что \ не расширяется. Доступ к одиночной кассе изнутри указанной строки возможен, потому что вы можете объединить строки с одинарными и двойными кавычками, например 'I'"'"'m', которые можно использовать для доступа к файлу с именем "I'm" (здесь также возможна двойная цитата).

Поэтому вам следует избегать всех управляющих символов, потому что их слишком сложно ввести в оболочку. Остальные по-прежнему забавные, особенно файлы, начинающиеся с тире, потому что большинство команд читают их как параметры, если у вас еще две черты -- раньше, или вы указываете их с помощью ./, который также скрывает начальный -.

Если вы хотите быть красивой, не используйте ни один из символов, которые оболочка и типичные команды используют в качестве синтаксических элементов, иногда зависимых от положения, например, вы все равно можете использовать -, но не как первый символ; то же самое с ., вы можете использовать его как первый символ только тогда, когда вы имеете в виду его ( "скрытый файл" ). Когда вы имеете в виду, ваши имена файлов - это escape-последовательности VT100;-), так что ls искажает вывод.

  • 0
    Вопрос не в снарядах.
-2

Хотя единственными незаконными символами Unix могут быть / и NULL, хотя необходимо учитывать некоторое отношение к интерпретации командной строки.

Например, хотя может быть законным назвать файл 1>&2 или 2>&1 в Unix, имена файлов, такие как это, могут быть неверно истолкованы при использовании в командной строке.

Аналогичным образом можно было бы назвать файл $PATH, но при попытке получить к нему доступ из командной строки оболочка переведет $PATH в значение переменной.

  • 0
    для литералов в BASH лучший способ объявления литералов без интерполяции - это $'myvalueis' , например: $ echo 'hi' > $'2>&1' , cat 2\>\&1 "hi"
-4

У меня была такая же потребность, и я искал рекомендации или стандартные ссылки и наткнулся на эту тему. Мой текущий черный список символов, которых следует избегать в именах файлов и каталогов:

$CharactersInvalidForFileName = {
    "pound" -> "#",
    "left angle bracket" -> "<",
    "dollar sign" -> "$",
    "plus sign" -> "+",
    "percent" -> "%",
    "right angle bracket" -> ">",
    "exclamation point" -> "!",
    "backtick" -> "`",
    "ampersand" -> "&",
    "asterisk" -> "*",
    "single quotes" -> """,
    "pipe" -> "|",
    "left bracket" -> "{",
    "question mark" -> "?",
    "double quotes" -> """,
    "equal sign" -> "=",
    "right bracket" -> "}",
    "forward slash" -> "/",
    "colon" -> ":",
    "back slash" -> "\\",
    "lank spaces" -> "b",
    "at sign" -> "@"
};
  • 3
    Вы не могли бы прокомментировать наличие @ в списке?
  • 7
    Вопрос заключался в том, какие символы являются незаконными. Большинство символов в вашем списке являются законными.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню