Есть ли эквивалент 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 есть:

  • PATH_MAX (определен в limits.h)

  • FILENAME_MAX (определен в stdio.h)

оба из них установлены на 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