Есть ли эквивалент максимального пути WinAPI под linux / unix?
Если я хочу выделить массив символов (в C), который гарантированно будет достаточно большим, чтобы содержать любой допустимый абсолютный путь+имя файла, насколько он должен быть большим.
на Win32 есть определение MAX_PATH. Что такое эквивалент для Unix / linux?
6 ответов:
есть
PATH_MAX, но это немного проблематично. Из раздела ошибки realpath (3) man page:POSIX.1-2001 стандартная версия этой функции нарушается дизайн, так как невозможно определить подходящий размер для выходной буфер, resolved_path. Согласно POSIX.1-2001 буфер размер PATH_MAX хватает, но PATH_MAX не обязательно быть определенным постоянный, и, возможно, придется быть получены с помощью pathconf(3). И спрашиваю pathconf(3) не помогает, так как, с одной стороны POSIX предупреждает, что результат pathconf(3) может быть огромным и непригодными для mallocing памяти, а с другой стороны pathconf(3) может вернуть -1, что означает PATH_MAXне ограниченный.
другие ответы до сих пор все кажутся правильными в отношении стороны *nix вещей, но я добавлю предупреждение об этом в Windows.
вы были обмануты (по упущению) документацией.
MAX_PATHдействительно определяется и, вероятно, даже применяется к файлам, хранящимся на FAT или FAT32. Однако любой путь может иметь префикс\?\рассказать API-интерфейса Windows, чтобы игнорироватьMAX_PATHи пусть драйвер файловой системы решает сам. После этого определения получают размытый.добавьте в микс тот факт, что имена путей на самом деле являются Unicode (ну, UTS-16) и что при использовании API "ANSI" преобразование во внутреннее имя Unicode и из него зависит от множества факторов, включая текущую кодовую страницу, и у вас есть рецепт путаницы.
хорошее описание правил для Windows находится в MSDN. Правила гораздо сложнее, чем я здесь резюмировал.
Edit: I изменилось
\.\до\?\в приведенном выше благодаря комментарию от KitsuneYMG.пути Windows и пространства имен являются сложными. Некоторые могут даже утверждать, что они слишком сложны. Одним из источников сложности является то, что Win32 (и теперь Win64) API является подсистемой, которая лежит поверх собственной системы Windows NT.
путь без какого-либо префикса совместим с самым широким диапазоном платформ Windows. Если он ограничен 7-битными символами ASCII, то он совместим с 16-битной DOS начиная с версии 2.0 или около того (всякий раз, когда были введены подкаталоги, которые могли бы быть на самом деле в DOS 3; но DOS 1.0 имел только корневые каталоги и
\символ не имел особого значения).The приводит к тому, что баланс имени пути передается дословно соответствующему драйверу файловой системы, что приводит к снижению ограничения до
MAX_PATHсимволы. Если длинный путь также находится в общей сетевой папке, то вы можно использовать расширенное UNC-имя для него с префиксом\?\UNC\server\share\вместо обычного имени UNC\server\share\. Использование этого префикса ограничивает переносимость на Win32 и более поздние платформы Windows, но если вам не требуется поддержка 16-разрядных окон на устаревшем оборудовании, это не большая проблема.The
\.\префикс-это разные животные. Он позволяет получить доступ к объектам устройств за пределами набора специально названных устройств, которые автоматически отображаются Windows в виде специальных имен файлов в каждый файл папка. Эти специальные названия: кон, ПРН, ОКС, нуль, СОМ1, СОМ2, СОМ3, порт com4, COM5, СОМ6, резолюцию com7, COM8, com9, то порт lpt1, lpt2 в, подключен к порту lpt3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9 и. Обратите внимание, что все эти имена являются особыми независимо от того, используется ли расширение или любое сочетание верхнего или нижнего регистра. Но возможно, что у вас установлено 10 или более COM-портов. Это происходит быстро, если вы играете с USB-модемами или адаптерами последовательного порта USB, так как каждому уникальному последовательному порту USB будет назначен отдельный COMn имя. Если вам нужно получить доступ к 50-му последовательному порту, то вы можете сделать это только с именем\.\COM50потому что COM50-это не специальное имя, такое как COM1.страница MSDN, которую я процитировал выше, имела право на различие, я просто набрал неверный префикс в своем исходном ответе.
ну, на Linux, по крайней мере, есть:
PATH_MAX(определена вlimits.h)
FILENAME_MAX(определена вstdio.h)оба из них установлены в
4096в моей системе (x86 Linux).обновление::некоторая информация из руководства glibc по этому
каждый из следующих макросов определяется в пределах.h только если система имеет фиксированное, равномерное ограничение для рассматриваемого параметра. Если система позволяет различным файловым системам или файлам иметь разные ограничения, то макрос не определен; используйте pathconf или fpathconf, чтобы узнать ограничение, которое применяется к конкретному файлу
FILENAME_MAX является частью стандарта ISO C, он работает на UNIX и Windows. Однако документация библиотеки GNU C содержит следующие предупреждения:
" В отличие от PATH_MAX, этот макрос определяется даже при отсутствии фактического ограничения. В таком случае его значение обычно является очень большим числом. Это всегда имеет место в системе GNU.
примечание по использованию: не используйте FILENAME_MAX как размер массива, в котором хранится имя файла! Ты не можешь сделать массив такой большой! Используйте динамическое распределение."
можно использовать
pathconf()чтобы выяснить во время выполнения, но есть также препроцессор PATH_MAX, определяемый в<limits.h>.
можно использовать
realpathфункция выделения буфера, достаточно большого для определенного пути. Если вы передадите ему нулевой указатель в качестве второго аргумента, он выделит буфер, достаточно большой для пути. Страница man, вероятно, объясняет это лучше, чем я могу:realpath () разворачивает все символьные ссылки и разрешает ссылки на /./, /../ и дополнительные символы ' / ' в строке с нулевым завершением, названной path, чтобы создать канонизированный абсолютный путь. Результирующий путь-это хранится как строка с нулевым завершением, до максимума байтов PATH_MAX, в буфере, на который указывает resolved_path. Результирующий путь не будет иметь символической ссылки,/./ или./ ./ комплектующие.
если resolved_path указан как NULL, то realpath () использует malloc (3) для выделения буфера до байтов PATH_MAX для хранения разрешенного пути и возвращает указатель на этот буфер. Вызывающий должен освободить этот буфер с помощью free (3).
Comments