Есть ли эквивалент WinAPI MAX_PATH в linux/unix?
Если я хочу выделить массив char (в C), который, как гарантируется, будет достаточно большим, чтобы удерживать любой действительный абсолютный путь + имя файла, насколько он должен быть.
В Win32 определяется MAX_PATH. Что эквивалентно для Unix/linux?
Ответы
Ответ 1
Существует PATH_MAX
, но это немного проблематично. Из раздела ошибок раздела realpath (3) man:
Стандартная версия этой функции POSIX.1-2001 нарушена дизайн, поскольку невозможно определить подходящий размер для выходной буфер, разрешенный_path. Согласно POSIX.1-2001, буфер размер PATH_MAX, но PATH_MAX не обязательно должен быть определен константа и может быть получена с помощью pathconf (3). А также запрос pathconf (3) действительно не помогает, поскольку, с одной стороны, POSIX предупреждает, что результат pathconf (3) может быть огромным и неподходящий для mallocing памяти, а с другой стороны pathconf (3) может возвращать -1, чтобы обозначить, что PATH_MAX не является ограничено.
Ответ 2
Остальные ответы до сих пор кажутся правильными в отношении стороны * nix, но я добавлю предупреждение об этом в Windows.
В соответствии с документацией вас обвиняют (путем упущения).
MAX_PATH
действительно определен и, возможно, даже применяется к файлам, хранящимся на FAT или FAT32. Однако любое имя пути может быть префикс \\?\
, чтобы сообщить Windows API игнорировать MAX_PATH
и позволить драйверу файловой системы самостоятельно. После этого определения становятся нечеткими.
Добавьте к смешению тот факт, что имена путей на самом деле являются Unicode (ну, UTS-16) и что при использовании API "ANSI" преобразование в и из внутреннего имени Юникода зависит от множества факторов, включая текущей кодовой страницы, и у вас есть рецепт для путаницы.
Хорошее описание правил для Windows - MSDN. Правила намного сложнее, чем здесь.
Изменить: Я изменил \\.\
на \\?\
в приведенном выше примере комментария KitsuneYMG.
Пути и пространства имен Windows сложны. Некоторые могут даже утверждать, что они слишком сложны. Одним из источников сложности является то, что Win32 (и теперь Win64) API - это подсистема, которая лежит поверх собственной системы Windows NT.
Путь без префикса совместим с широким диапазоном платформ Windows. Если он ограничен 7-разрядными символами ASCII, то он совместим с 16-разрядной DOS с версии 2.0 или около того (всякий раз, когда были введены подкаталоги, которые могли бы быть в DOS 3, но в DOS 1.0 были только корневые каталоги, а \
не имел особого значения).
Префикс \\?\
приводит к тому, что баланс имени пути передается дословно на соответствующий драйвер файловой системы, что и дает эффект отбрасывания ограничения на символы MAX_PATH
. Если имя длинного пути также включено в общий сетевой ресурс, вы можете использовать для него расширенное имя UNC с префиксом \\?\UNC\server\share\
вместо обычного UNC-имени \\server\share\
. Использование этого префикса ограничивает переносимость для платформ Win32 и более поздних версий Windows, но если вам не нужна поддержка 16-разрядных Windows на устаревшем оборудовании, это не большая проблема.
Префикс \\.\
- другое животное. Он позволяет получить доступ к объектам устройства за пределами набора специально названных устройств, которые автоматически сопоставляются Windows как специальные имена файлов в каждой папке файла. Эти специальные имена включают CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 и LPT9. Обратите внимание, что все эти имена являются особенными независимо от того, используется ли расширение или в любом сочетании верхнего или нижнего регистра. Но возможно, что у вас установлено 10 или более COM-портов. Это происходит быстро, если вы играете с USB-модемами или адаптерами последовательного порта USB, поскольку каждому уникальному USB-порту последовательного порта будет присвоено отдельное имя COMn. Если вам нужно получить доступ к 50-му последовательному порту, вы можете сделать это только с именем \\.\COM50
, потому что COM50 не является специальным именем, например COM1.
Страница MSDN, указанная выше, имела право на различие, я просто набрал неверный префикс в своем первоначальном ответе.
Ответ 3
Ну, по крайней мере на Linux есть:
оба из них установлены на 4096
в моей системе (x86 Linux).
Обновление:: Некоторая информация из руководства glibc по этому вопросу
Каждый из следующих макросов определяется в пределах .h, только если система имеет фиксированный равномерный предел для рассматриваемого параметра. Если система позволяет различным файловым системам или файлам иметь разные пределы, макрос undefined; используйте pathconf или fpathconf, чтобы узнать ограничение, которое применяется к определенному файлу
Ответ 4
FILENAME_MAX является частью стандарта ISO C, он работает в UNIX и Windows. Однако документация библиотеки GNU C содержит следующие предупреждения:
"В отличие от PATH_MAX, этот макрос определяется, даже если фактического ограничения не установлено. В таком случае его значение обычно является очень большим числом. Это всегда происходит в системе GNU.
Примечание по использованию: не используйте FILENAME_MAX как размер массива, в котором необходимо сохранить имя файла! Вы не можете сделать массив такой большой! Используйте динамическое распределение.
Ответ 5
Вы можете использовать pathconf()
для определения во время выполнения, но также препроцессор PATH_MAX определяет в <limits.h>
.
Ответ 6
Вы можете использовать функцию realpath
, чтобы выделить буфер, достаточно большой для определенного пути. Если вы передадите ему нулевой указатель в качестве второго аргумента, он выделит буфер, достаточно большой для пути. Страница пользователя, вероятно, объясняет это лучше, чем я могу:
realpath() расширяет все символические ссылки и разрешает ссылки на/./,/../и дополнительные символы '/' в строке с нулевым символом по имени, чтобы создать каноническое абсолютное имя пути. Полученное имя пути хранится в виде строки с нулевым завершением, вплоть до максимального количества байтов PATH_MAX, в буфере, на который указывает разрешенный_path. Результирующий путь не будет иметь символической ссылки,/./или/../.
Если resol_path указан как NULL, то realpath() использует malloc (3) для распределения буфера до байтов PATH_MAX для хранения разрешенного пути и возвращает указатель на этот буфер. Вызывающий должен освободить этот буфер, используя бесплатный (3).
http://linux.die.net/man/3/realpath
Ответ 7
limits.h
/*
* File system limits
*
* NOTE: Apparently the actual size of PATH_MAX is 260, but a space is
* required for the NUL. TODO: Test?
* NOTE: PATH_MAX is the POSIX equivalent for Microsoft MAX_PATH; the two
* are semantically identical, with a limit of 259 characters for the
* path name, plus one for a terminating NUL, for a total of 260.
*/
#define PATH_MAX 260
minwindef.h
#define MAX_PATH 260