Каково максимальное количество символов или длина для Справочника?

Каково максимальное количество символов, которое может содержать типичный путь для каталога при использовании С#?

Например, C:\test\ имеет 7 символов в длину, какая максимальная длина?

Ответы

Ответ 1

Максимальное значение MaxPath в CLR составляет 260 символов.

Максимальное количество символов определяется MAX_PATH в библиотеке Win32 API. Этот параметр равен 260, и этот же параметр используется в жестком коде внутри CLR BCL. Путь, достигающий такого количества символов, может вызвать проблемы (см. Ниже). Этот максимум является максимумом для старых добрых FAT и FAT32.

И наоборот, файловая система NTFS, используемая в большинстве установок Windows по умолчанию, имеет максимум 32767 символов и поддерживает юникод (в реализации, где каждый символ может занимать 2 байта, т.е. UCS-2, а не UTF-32). Но даже в NTFS один сегмент пути не должен превышать 255 символов. Хотя NTFS поддерживает очень длинные имена файлов, большинство приложений, включая любые приложения .NET, использующие System.IO, не смогут видеть эти имена файлов.

Почему 260, а не 256? Поскольку спецификатор диска, первая обратная косая черта и завершающий нулевой символ не являются частью ограничений по длине. Вы можете получить эту информацию для Windows, используя GetVolumeInformation, которую вы должны запрашивать для каждого тома индивидуально (каждый том может иметь разный максимальный размер).

Я взял на себя Windows. Linux и другие ОС могут и будут отличаться. Начиная с Windows 10, сборка 1607, этот предел был удален, подробности см. Ниже.


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

try
{
    SetCurrentDirectory(longPath);
}
catch(PathTooLongException exc)
{
    Console.WriteLine("The pathname was too long");
}

Примечание: приведенный выше код будет выдан, когда вы превысите 260 символов, что является пределом, который CLR накладывает на вас. Это не реальный предел (см. Первый абзац).

Как в стороне на .NET

Microsoft подтвердила, что с текущей реализацией (-ями).NET связана проблема, заключающаяся в том, что вы не можете надежно определить, какой максимальный размер пути соответствует CLR. Если вы хотите получить эту информацию программно, используйте свойство Path.MaxPath. Однако свойство является internal что означает, что вы можете получить к нему доступ только через отражение, и что вы не можете гарантировать, что оно будет работать в разных версиях или в других реализациях BCL (Mono):

// reflection
FieldInfo maxPathField = typeof(Path).GetField("MaxPath", 
    BindingFlags.Static | 
    BindingFlags.GetField | 
    BindingFlags.NonPublic );

// invoke the field gettor, which returns 260
int MaxPathLength = (int) maxPathField.GetValue(null);

Примечание: это дает вам максимальный путь, который используется реализацией Microsoft.NET. В BCL есть другое значение для максимального размера каталога, Path.MAX_DIRECTORY_PATH, но даже внутри BCL это никогда не используется. Если вы когда-либо создадите каталог, равный этому размеру, вы не сможете разместить какие-либо файлы в этом каталоге. Хуже того, простое его открытие вызовет ошибку (из-за обязательных псевдонимов полукаталогов . И .., которые приводят к аварийному завершению многих API).


ОБНОВЛЕНИЕ: начиная с Windows 10 Build 1607 вы можете удалить ограничение через OptIn в реестре:

Начиная с Windows 10 версии 1607 ограничения MAX_PATH были удалены из общих функций файлов и каталогов Win32. Тем не менее, вы должны подписаться на новое поведение.

Раздел реестра позволяет вам включить или отключить новый длинный путь поведения. Чтобы включить поведение длинного пути, установите ключ реестра в HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Тип: REG_DWORD).

Дополнительная информация содержится в обновленной записи в MSDN, раздел "Ограничение максимальной длины пути".