Вопрос

Если я хочу выделить массив символов (на C), который гарантированно будет достаточно большим, чтобы содержать любой допустимый абсолютный путь + имя файла, насколько большим он должен быть.

В Win32 есть определение MAX_PATH .Что является эквивалентом для Unix / linux?

Это было полезно?

Решение

Есть PATH_MAX, но это немного проблематично. Из раздела ошибок realpath (3) справочной страницы:

  

POSIX.1-2001 стандартная версия этой функции нарушена   дизайн, так как невозможно определить подходящий размер для   выходной буфер, resolved_path . Согласно POSIX.1-2001 буфер   размера PATH_MAX достаточно, но PATH_MAX не обязательно должен быть определен   константа, и может потребоваться получить с помощью pathconf (3) , А также    pathconf (3) не очень помогает, так как одна рука   POSIX предупреждает, что результат pathconf (3) может быть огромным а также   не подходит для неправильной памяти, а с другой стороны    pathconf (3) может вернуть -1, чтобы показать, что PATH_MAX нет   ограничено.

Другие советы

Все остальные ответы пока кажутся правильными в отношении * nix-стороны вещей, но я добавлю предупреждение об этом в Windows.

Документация обманула вас (по недомолвке).

MAX_PATH действительно определен и, вероятно, даже применим к файлам, хранящимся в FAT или FAT32.Однако любое имя пути может иметь префикс \\?\ чтобы указать Windows API игнорировать MAX_PATH и пусть драйвер файловой системы принимает решение сам.После этого определения становятся расплывчатыми.

Добавьте к этому тот факт, что имена путей на самом деле являются Unicode (ну, UTS-16) и что при использовании API "ANSI" преобразование во внутреннее имя Unicode и обратно зависит от множества факторов, включая текущую кодовую страницу, и вы получите рецепт путаницы.

Хорошее описание правил для 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, которую я процитировал выше, имела правильное различие, я просто ввел неправильный префикс в своем первоначальном ответе.

Ну, по крайней мере, в 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 в качестве размера массива, в котором хранится имя файла! Вы не можете сделать массив таким большим! Использовать динамическое размещение. & Quot;

Вы можете использовать pathconf(), чтобы выяснить это во время выполнения, но в <limits.h> также есть определение препроцессора PATH_MAX.

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

  

realpath () раскрывает все символические ссылки и разрешает ссылки на /./, /../ и дополнительные символы '/' в строке с нулевым символом в конце, названной path, чтобы создать канонизированный абсолютный путь. Полученный путь сохраняется в виде строки с нулевым символом в конце, максимум до байтов PATH_MAX, в буфере, указанном resolved_path. Полученный путь не будет иметь символической ссылки, компонентов / ./ или /../.

     

Если resolved_path указан как NULL, то realpath () использует malloc (3) для выделения буфера размером до байтов PATH_MAX для хранения разрешенного пути и возвращает указатель на этот буфер. Вызывающий должен освободить этот буфер, используя free (3).

http://linux.die.net/man/3/realpath

пределы.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's 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top