Максимальная длина пути к файлу: 259 или 258 символов?

Максимальная длина пути к файлу: 259 или 258 символов?

Я пытаюсь понять, какова максимально допустимая длина пути к файлу.

Для этого я использую стандартный файловый менеджер Windows (в Windows 7) и следующий скрипт PowerShell:

Get-ChildItem | Select Name, FullName, @{N="Path Length";E={$_.FullName.Length}} | Format-List

Я открываю менеджер, создаю файл abc.txtв C:\, а затем добавляю буквы в abcстолько, сколько позволяет файловый менеджер. (На самом деле, я, конечно, использую копирование и вставку. Это намного быстрее.)

Затем я провожу тот же тест в C:\aaaи C:\aaa\bbb.

По какой-то причине результаты разные. Максимальная длина в C:\aaaи C:\aaa\bbbсоставляет 259 символов, а максимальная длина в C:\составляет 258 символов. Почему?

C:\abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefgh.txt
258 characters

C:\aaa\abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcde.txt
259 characters

C:\aaa\bbb\abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_a.txt
259 characters

обновлять

Список Python с mail-archive.com:

(https://www.mail-archive.com/[email protected]/msg444514.html)

классические ограничения длины пути DOS (например, 247, 258 или 259 символов в зависимости от контекста).

Приведенные ниже пояснения принадлежат мне.

247 обозначает максимальную длину пути к каталогу: 260 - 12 - 1 = 247. Здесь 12 обозначает имя файла 8.3, а 1 обозначает терминатор NUL. Например, C:\fooилиC:\foo\bar

259 обозначает максимальную длину путифайл(не каталог) располагаетсянетв корне диска. Например,C:\foo\aaa.txt

258 обозначает максимальную длину путифайл(не каталог) располагаетсявкорень диска. Например,C:\aaa.txt

Таким образом, на самом деле существует три предела: 247, 258 и 259.

Но почему у нас ограничение в 258 файлов в корне диска и 259 файлов в других каталогах?

Смотрите также:https://www.mail-archive.com/[email protected]/msg106171.html

MAX_PATH, который ограничивает длину пути к файлам всего 259 символами (без завершающего нуля); длину текущего каталога — 258 символами (без завершающей обратной косой черты и нуля); а длину пути к новому каталогу — 247 символами (вычтите 12 из 259, чтобы оставить место для имени файла 8.3).

Однако вторая цитата мне не понятна. Я не могу понять, почему этот парень говорит о завершающем обратном слеше. Завершающий обратный слеш может быть тем случаем, когда мы говорим о каталогах, но не о файлах!

решение1

У меня есть простое объяснение этой разницы: плохой код в Windows 7, переписанный заново в Windows 10. Ниже я покажу, почему я так думаю, и каковы правила относительно длины имен файлов в Windows 7 и 10.

Но сначала небольшое замечание: ограничение в 260 МАКС_ПУТЬ является артефактом гораздо более ранней версии Windows. Его нельзя изменить, поскольку Windows API активно использует его в своих структурах данных, например, в WIN32_FIND_DATA, так что увеличение его в API приведет к переполнению памяти в существующих приложениях. Вот почему длинные имена файлов должны быть явно разрешены в реестр и программа должна объявить в своем манифесте о своей способности обрабатывать длинные имена.

Я также отмечаю, что буква диска ( C:\) включена только в текст и не относится к таблицам дисков Windows (MFT). Windows хорошо знает, на каком диске находится файл.

Ниже приведены мои тесты в Windows 7, результаты которых подтверждают выводы автора:

введите описание изображения здесь

Можно вывести следующие правила:

  • Буква диска не учитывается при расчете лимита ( C:)
  • Начальная обратная косая черта не учитывается в расчетах пределов ( C:\)
  • Остальное ограничено 256 символами, включая промежуточные обратные косые черты.
  • Длина корневого файла может достигать 255 символов, чего не могут сделать файлы в папках.

Эти бессмысленные результаты однозначно указывают на плохо написанный код.

Для начала, что касается MFT, каждый компонент пути является отдельным и имеет точно такие же ограничения по длине, как и любой другой компонент (подпапка), поэтому нет никаких причин, присущих дисковым таблицам, ограничивать длину имен файлов только потому, что они включены в какую-то папку.

Во-вторых, у нас возникает вопрос, почему корневой файл ограничен 255 символами, когда, казалось бы, он должен быть 256, поскольку это единственный элемент в его пути (который, как мы видели, может достигать 256 символов).

В поисках объяснения я предположил, что 255 — это реальный предел для имен файлов, установленный Microsoft, а все остальное — просто плохо написанный код.

Чтобы проверить эту теорию, я протестировал поведение Windows 10. Я повторил те же операции (для записи в ) (требуются права администратора C:\):

введите описание изображения здесь

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

Стало ясно, что изначально Microsoft намеревалась разрешить использовать имена файлов длиной 255 символов, но в Windows 7 это было отключено кодом, учитывающим путь, причем без какой-либо веской причины.

Дальнейшие раскопки обнаружили документацию для NTFS Атрибут - $FILE_NAME (0x30), который указывает один байт для длины имени файла (по смещению 0x40). Это хорошо объясняет ограничение в 255 символов. (См. также FireEye Часть 2: Внутренняя структура атрибута имени файла).

Небольшой анекдот: Согласно закону Microsoft о сохранении ошибок, проводник Windows 10 не смог удалить файлы длиной 255 символов в C:\, C:\Tempи C:\Temp\abc. Мне пришлось ввести в командной строке команду, del 12*чтобы избавиться от них. (Исправить одну ошибку, одновременно вводя другую...)

решение2

По какой-то причине результаты разные. Максимальная длина в C:\aaa и C:\aaa\bbb составляет 259 символов, но максимальная длина в C:\ составляет 258 символов. Почему?

Думаю, вы спрашиваете, какова максимальная длина пути, обычно допускаемая проводником Windows. 260 символов.

Это позволяет ввести 248 символов для пути и 12 символов для имени файла.

Имена файлов ваших примеров отличаются из-за нулевого символа.

В редакциях Windows до Windows 10 версии 1607 максимальная длина пути составляет MAX_PATH, что определяется как 260 символов. В более поздних версиях Windows для снятия ограничения требуется изменение раздела реестра или использование инструмента групповой политики.

В Windows API (за некоторыми исключениями, обсуждаемыми в следующих параграфах) максимальная длина пути составляет MAX_PATH, что определяется как 260 символов. Локальный путь структурирован в следующем порядке: буква диска, двоеточие, обратная косая черта, компоненты имени, разделенные обратной косой чертой, и завершающий нулевой символ. Например, максимальный путь на диске D — это "D:\some 256-character path string", где "" представляет собой невидимый завершающий нулевой символ для текущей системной кодовой страницы. (Символы < > используются здесь для наглядности и не могут быть частью допустимой строки пути.)

Источник:

решение3

Необходимо учитывать два ограничения: одно — максимальная длина пути, другое — максимальная длина имени файла. В NTFS,Имена файлов могут содержать до 255 кодовых точек UTF-16., без нулевого байта (см. стр. 12).

abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefgh.txtимеет длину ровно 255 символов.

Связанный контент