Почему в Windows существует ограничение длины пути в 260 символов?

Не является прямым решением, но в целом я счел целесообразным переместить как можно больше выделения из статического времени инициализации. Обычно это приводит к головным болям (порядок инициализации, порядок инициализации и т. Д.).

Если это слишком сложно, вы можете вызвать _CrtMemCheckpoint ( http://msdn.microsoft.com/en- us / library / h3z85t43% 28VS.80% 29.aspx ) в начале main() и _CrtMemDumpAllObjectsSince в конце.

366
задан Jeffrey Cameron 10 December 2009 в 11:18
поделиться

11 ответов

Цитировать эту статью https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

Ограничение максимальной длины пути

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

Теперь мы видим, что это 1 + 2 + 256 + 1 или [диск] [ : \] [path] [null] = 260. Можно предположить, что 256 - это разумная фиксированная длина строки из дней DOS. Возвращаясь к API DOS, мы понимаем, что система отслеживала текущий путь на диск, и у нас есть 26 (32 с символами) максимум дисков (и текущие каталоги).

INT 0x21 AH = 0x47 говорит: «Эта функция возвращает описание пути без буквы диска и начальной обратной косой черты». Итак, мы видим, что система сохраняет CWD в виде пары (диск, путь), и вы запрашиваете путь указав диск (1 = A, 2 = B,…), если вы укажете 0, то он принимает путь для диска, возвращенный INT 0x21 AH = 0x15 AL = 0x19. Итак, теперь мы знаем, почему это 260, а не 256, потому что эти 4 байта не хранятся в строке пути.

Почему 256-байтовая строка пути, потому что 640 КБ достаточно ОЗУ.

211
ответ дан John Cummings 10 December 2009 в 11:18
поделиться

Это не совсем так, поскольку файловая система NTFS поддерживает пути длиной до 32 тыс. Символов. Вы можете использовать API-интерфейс win32 и префикс пути «\\?\», чтобы использовать более 260 символов.

Подробное объяснение длинного пути из блога .Net BCL team .
Небольшая выдержка подчеркивает проблему с длинными путями

Еще одной проблемой является непоследовательное поведение, которое может возникнуть в результате предоставления поддержки длинных путей. Длинные пути с префиксом \\?\ могут использоваться в большинстве файловых API Windows, но не во всех Windows API. Например, LoadLibrary, который отображает модуль на адрес вызывающего процесса, завершается ошибкой, если имя файла длиннее, чем MAX_PATH. Таким образом, это означает, что MoveFile позволит вам переместить библиотеку DLL в такое место, где ее путь будет длиннее 260 символов, но при попытке загрузить библиотеку DLL произойдет сбой. Есть аналогичные примеры в Windows API; Существуют некоторые обходные пути, но они применяются в каждом конкретном случае.

142
ответ дан dthorpe 10 December 2009 в 11:18
поделиться

Вопрос в , почему ограничение все еще существует. Конечно, современные Windows могут увеличить сторону MAX_PATH, чтобы позволить более длинные пути. Почему ограничение не было снято?

  • Причина, по которой оно не может быть удалено, заключается в том, что Windows пообещала, что оно никогда не изменится.

Благодаря API-контракту Windows гарантировала всем приложениям, что стандартные файловые API никогда не будут возвращать путь, длина которого превышает 260 символов.

Рассмотрим следующий правильный код:

WIN32_FIND_DATA findData;

FindFileFirst("C:\Contoso\*", ref findData);

Windows гарантировала моей программе, что она заполнит мою WIN32_FIND_DATA структуру:

WIN32_FIND_DATA {
   DWORD    dwFileAttributes;
   FILETIME ftCreationTime;
   FILETIME ftLastAccessTime;
   FILETIME ftLastWriteTime;
   //...
   TCHAR    cFileName[MAX_PATH];
   //..
}

Мое приложение не объявляло значение константы MAX_PATH, это сделал Windows API. Мое приложение использовало это определенное значение.

Моя структура правильно определена и выделяет всего 592 байт. Это означает, что я могу получить только имя файла, длина которого меньше 260 символов. Windows пообещала мне, что если я напишу свое приложение правильно, мое приложение продолжит работать в будущем.

Если бы Windows разрешала имена файлов длиннее 260 символов, то мое существующее приложение (которое правильно использовало правильный API) не работало бы.

Для тех, кто призывает Microsoft изменить константу MAX_PATH, сначала необходимо убедиться, что ни одно из существующих приложений не дает сбой. Например, я все еще владею и использую приложение Windows, которое было написано для работы в Windows 3.11. Он по-прежнему работает на 64-битной Windows 10. Это то, что дает вам обратная совместимость.

Microsoft создала способ использования полных 32 768 путей; но они должны были создать новый контракт API для этого. Например, вы должны использовать Shell API для перечисления файлов (поскольку не все файлы существуют на жестком диске или в сетевой папке).

Но они также не должны ломать существующие пользовательские приложения. Подавляющее большинство приложений не используют API оболочки для работы с файлами. Все просто звонят FindFirstFile / FindNextFile и называют это днем.

100
ответ дан Wai Ha Lee 10 December 2009 в 11:18
поделиться

В Windows 10. вы можете снять ограничение , изменив ключ реестра.

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

Раздел реестра позволяет вам включить или отключить новое поведение длинного пути. Чтобы включить поведение длинного пути, установите ключ реестра в HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Тип: REG_DWORD). Значение ключа будет кэшироваться системой (для каждого процесса) после первого вызова уязвимой функции файла или каталога Win32 (список следует). Раздел реестра не будет перезагружен в течение всего жизненного цикла процесса. Чтобы все приложения в системе могли распознать значение ключа, может потребоваться перезагрузка, поскольку некоторые процессы могли быть запущены до того, как ключ был установлен. Раздел реестра также можно контролировать с помощью групповой политики на Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths. Вы также можете включить новое поведение длинного пути для приложения через манифест:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
        <ws2:longPathAware>true</ws2:longPathAware>
    </windowsSettings>
</application>
53
ответ дан Bram Vanroy 10 December 2009 в 11:18
поделиться

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

Например:

  1. создайте каталог C:\p для хранения коротких ссылок на длинные пути
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. добавьте C:\p\foo к вашему пути вместо длинного пути
16
ответ дан BaCaRoZzo 10 December 2009 в 11:18
поделиться

Что касается , почему это все еще существует - MS не считает это приоритетом и ценит обратную совместимость по сравнению с продвижением своих ОС (по крайней мере, в этом случае).

Обходной путь, который я использую, состоит в том, чтобы использовать «короткие имена» для каталогов в пути, вместо их стандартных, удобочитаемых версий. Так например для C:\Program Files\ я бы использовал C:\PROGRA~1\. Вы можете найти эквиваленты короткого имени, используя dir /x.

7
ответ дан Conrad 10 December 2009 в 11:18
поделиться

Что касается того, как справиться с ограничением размера пути в Windows - использование 7zip для упаковки (и распаковки) ваших файлов, чувствительных к длине пути, кажется приемлемым обходным путем. Я использовал его для переноса нескольких инсталляций IDE (эти пути к подключаемым модулям Eclipse, yikes!) И груды автоматически сгенерированной документации, и до сих пор не было ни одной проблемы.

Не совсем уверен, как он уклоняется от ограничения в 260 символов, установленного Windows (из технической точки зрения), но эй, это работает!

Более подробная информация на их странице SourceForge здесь :

«NTFS может фактически поддерживать имена путей длиной до 32 000 символов.»

7 -zip также поддерживает такие длинные имена.

Но это отключено в коде SFX. Некоторым пользователям не нравятся длинные пути, так как они не понимают, как с ними работать. Вот почему я отключил его в коде SFX.

и заметки о выпуске :

9.32 alpha 2013-12-01

  • Улучшена поддержка имен файлов длиннее 260 символов .

4.44 beta 2007-01-20

  • 7-Zip теперь поддерживает имена файлов длиннее 260 символов.

ВАЖНОЕ ПРИМЕЧАНИЕ: Чтобы это работало правильно, вам нужно указать путь назначения в диалоговом окне «Извлечь» 7zip напрямую, а не перетаскивание & amp; сбросив файлы в нужную папку. В противном случае папка «Temp» будет использоваться в качестве промежуточного кэша, и вы попадете в то же ограничение в 260 символов, как только Windows Explorer начнет перемещать файлы в их «окончательное место покоя». См. Ответы на на этот вопрос для получения дополнительной информации.

7
ответ дан Community 10 December 2009 в 11:18
поделиться

Вы можете включить длинные имена путей с помощью PowerShell:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1 

Другая версия заключается в использовании групповой политики в Computer Configuration / Administrative Templates / System / Filesystem:

Group Policy Editor

6
ответ дан MovGP0 10 December 2009 в 11:18
поделиться

Это так, и по какой-то причине это значение по умолчанию, но вы можете легко переопределить его с помощью этого ключа реестра:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001

См .: https://blogs.msdn.microsoft. ком / jeremykuhne / 2016/07/30 / нетто-4-6-2-и-длинный-путь-на-окна-10 /

4
ответ дан shA.t 10 December 2009 в 11:18
поделиться

Еще один способ справиться с этим - использовать Cygwin, в зависимости от того, что вы хотите сделать с файлами (то есть, если команды Cygwin удовлетворяют вашим потребностям)

Например, он позволяет копировать, перемещать или переименовывать файлы, которые даже Windows Explorer не может. Или, конечно, иметь дело с их содержимым, таким как md5sum, grep, gzip и т. Д.

Также для программ, которые вы кодируете, вы можете связать их с Cygwin DLL, и это позволит им использовать длинные пути (хотя я не проверял это, хотя)

2
ответ дан eliblanco87 10 December 2009 в 11:18
поделиться

Вы можете смонтировать папку как диск. Из командной строки, если у вас есть путь C:\path\to\long\folder, вы можете сопоставить его с буквой диска X:, используя:

subst x: \path\to\long\folder
29
ответ дан BaCaRoZzo 10 December 2009 в 11:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: