Должен ли я иметь дело с файлами длиннее, чем MAX_PATH? - PullRequest
30 голосов
/ 13 мая 2010

Просто был интересный случай.

Мое программное обеспечение сообщило об ошибке, вызванной длиной пути, превышающей MAX_PATH.

Путь был просто старым документом в Моих документах, например ::

C:\Documents and Settings\Bill\Some Stupid FOlder Name\A really ridiculously long file thats really very very very..........very long.pdf

Общая длина 269 символов (MAX_PATH == 260).

Пользователь не использовал внешний жесткий диск или что-то подобное. Это был файл на управляемом диске Windows.

Так что мой вопрос таков. Должен ли я заботиться?

Я не говорю, может Я имею дело с длинными путями, я спрашиваю следует I. Да, я знаю о взломе "\? \" Юникода на некоторые Win32 API, но кажется, что этот хак не без риска (так как он изменяет поведение способов синтаксического анализа API), а также не поддерживается всеми API.

Так или иначе, позвольте мне высказать свою позицию / утверждения:

  1. Во-первых, предположительно, единственный способ, которым пользователь смог преодолеть это ограничение, - это если приложение, которое оно использовало, использует специальный хак Unicode. Это файл PDF, так что, возможно, инструмент PDF, который она использовала, использует этот хак.
  2. Я попытался воспроизвести это (с помощью хака Unicode) и экспериментировал. Я обнаружил, что, хотя файл появляется в Проводнике, я ничего не могу с ним поделать. Я не могу открыть его, я не могу выбрать «Свойства» (Windows 7). Другие распространенные приложения не могут открыть файл (например, IE, Firefox, Notepad). Проводник также не позволит мне создавать файлы / каталоги, которые слишком длинные - он просто отказывается. То же самое для инструмента командной строки cmd.exe.

Так что, в принципе, можно посмотреть на это так: инструмент румян позволил пользователю создать файл, который недоступен для многих Windows (например, Explorer). Я мог бы прийти к выводу, что мне не придется иметь дело с этим.

(Кроме того, это не голосование об одобрении короткой максимальной длины пути: я думаю, что 260 символов - это шутка, я просто говорю, что если оболочка Windows и некоторые API не могут обрабатывать> 260, то почему я должен?).

Итак, это справедливый взгляд? Должен ли я сказать «Не моя проблема»?

ОБНОВЛЕНИЕ: Просто у другого пользователя была такая же проблема. На этот раз mp3-файл. Я что-то пропустил? Как эти пользователи могут создавать файлы, которые нарушают правило MAX_PATH?

Ответы [ 8 ]

12 голосов
/ 13 мая 2010

Это не настоящая проблема. NTFS поддерживает имена файлов до 32K ( 32,767 широких символов ). Вам нужно только использовать правильный API и правильный синтаксис имен файлов. Основное правило: имя файла должно начинаться с '\\?\' (см. http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx) как \\?\C:\Temp. Тот же синтаксис, который вы можете использовать с UNC: \\?\UNC\Server\share\Path. Важно понимать, что вы можете использовать только небольшое подмножество функции API. Например, посмотрите MSDN описание функций

CreateFile
CreateDirectory 
MoveFile

и т. Д.

вы найдете текст как:

В ANSI-версии этой функции имя ограничено MAX_PATH персонажи. Расширить этот лимит до 32 767 широких символов, позвоните Unicode версия функции и добавьте "\? \" к пути. Для большего информацию см. в разделе «Наименование файла».

Эти функции вы можете безопасно использовать. Если у вас есть дескриптор файла из CreateFile, вы можете использовать все остальные функции hFile (ReadFile, WriteFile и т. Д.) Без каких-либо ограничений.

Если вы пишете такую ​​программу, как сканер вирусов или программное обеспечение для резервного копирования, или какое-либо хорошее программное обеспечение, работающее на сервере, вы должны написать свою программу так, чтобы все операции с файлами поддерживали имена файлов длиной до 32K символов, а не MAX_PATH символы.

10 голосов
/ 13 мая 2010

Это ограничение включается в лот программного обеспечения, написанного на C или C ++. Включая код MSFT, хотя они от него отказались. Это только частично ограничение Win32, но оно по-прежнему имеет жесткий верхний предел длины имени файла (не пути), например, через WIN32_FIND_DATA. Одна из причин, по которой даже .NET имеет ограничения по длине . Это не исчезнет в ближайшее время, Win32 все еще сильна, и строка C каменного века не исчезнет.

Ваш клиент вряд ли будет ему симпатизировать, без сомнения, вероятно, пока вы не покажете ему другую программу, которая так же не работает. Однако убедитесь, что ваш код надежно может обнаружить потенциальное переполнение буфера строки, после чего следует разумная диагностика. Нет симпатии к программам бомбардировки на кучу коррупции.

6 голосов
/ 14 мая 2010

Как вы упомянули, многие функции оболочки Windows работают только на пути до MAX_PATH. Windows XP и я полагаю, что Vista имеет проблемы в проводнике при вложении каталогов с длинными именами файлов. Я не проверял Windows 7 - возможно, они исправили это. К сожалению, это означает, что пользователям трудно просматривать эти файлы.

Если вы действительно хотите поддерживать длинные пути, вам нужно проверить все функции, которые вы используете в Shell32.dll, которые используют пути, чтобы убедиться, что они поддерживают длинные пути. Для тех, кому это не нужно, напишите их самостоятельно, используя функции Kernel32.

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

Просто чтобы добавить еще одну пару измерений к проблеме, помните, что имена файлов - UTF-16, и вы можете столкнуться с файловыми системами не NTFS или FAT, которые могут быть чувствительны к регистру!

5 голосов
/ 13 мая 2010

Ваши собственные API не должны жестко кодировать фиксированное ограничение длины пути (или любые другие жесткие ограничения); тем не менее, вы не должны нарушать предварительные условия системных API для выполнения какой-либо задачи. ИМХО, тот факт, что Windows ограничивает длину имен путей, абсурден и должен рассматриваться как ошибка. Тем не менее, нет, я бы посоветовал вам не пытаться использовать различные системные API-интерфейсы, кроме тех, которые описаны в документации, даже если это приводит к определенному нежелательному поведению, такому как ограничение максимальной длины пути. Короче говоря, ваше мнение абсолютно справедливо; если ОС не поддерживает его, то ОС не поддерживает его. Тем не менее, вы можете дать понять пользователям, что это ограничение Windows, а не вашего собственного кода.

2 голосов
/ 12 января 2011

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

Пример:

"C: \Моя папка veeeeeeeeeeeeeeeeeeeeery looooooooooooooooooong "может быть разделена как" данные ".Затем пользователи могут получить доступ к этой папке через UNC-путь \\ computer \ data или (еще короче) через букву диска (M: \), предполагая, что M: сопоставлен с \\ computer \ data.

Это частопроисходит на файловых серверах.

1 голос
/ 07 июля 2013

Я занимаюсь программированием на C и искал способ получить максимальную длину заданного имени файла, после поиска MAX_PATH я наткнулся на эту ветку и после сомнений по этому вопросу и после прочтения комментариев к этому Я пришел к следующему выводу.

Итак, я понимаю, что NTFS поддерживает имена файлов длиной до 32,767 символов, однако, согласно знаниям, FAT16 поддерживает только имена файлов из 11 символов, 8 + 3, поэтому в реальных операционных системах должна быть функция, которую наша программа может вызывать для определения максимальный размер файла, просто потому что все файловые системы имеют разные ограничения, включая длину имени файла.

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

1 голос
/ 25 сентября 2012

Путь часто может быть больше 260, одним примером может быть, когда символические ссылки вкладываются и повторяются снова и снова, иногда даже специально. Я думаю, что программисты должны думать о том, хотят ли они, чтобы их программа справлялась с этими безумно большими путями или нет. ИМО, 260 МНОГО пространства, но это только я. Мой ответ на это:

если вам нужно так глубоко спросить себя о нарушении лимита в 260 символов, то это, вероятно, то, что вы должны сделать. Мы часто ищем подтверждения, когда собираемся сделать что-то, в чем мы не уверены ...

Я думаю, что максимальный путь в API составляет около 32 КБ, но это зависит от вас. В те времена это был довольно большой кусок изменений (половина целого сегмента памяти !! шиш!), Но в наши дни, в сегментарной прозрачной среде адресации, в которой мы живем, где вся память накапливается на плоской платформе, 32 КБ ничего ... Пути AFAIK не должны быть такими длинными, если вы не используете какой-то причудливый язык юникода, требующий много других символов, и т. д., и т. д., мы могли бы болтать об этом весь день, но вы понимаете. Я надеюсь, что это помогает ..... или болит?

0 голосов
/ 16 февраля 2013

Не совсем ответ на ваш конкретный вопрос, но он может помочь тем, кому нужно обрабатывать длинные имена файлов.

Библиотека Delimon - это библиотека на основе .NET Framework 4 в Microsoft TechNet для преодоления проблемы длинных имен файлов:

Библиотека Delimon.Win32.I O (V4.0) .

Он имеет свои собственные версии ключевых методов из System.IO. Например, вы должны заменить:

System.IO.Directory.GetFiles

с

Delimon.Win32.IO.Directory.GetFiles

, который позволит вам обрабатывать длинные файлы и папки.

С сайта:

Delimon.Win32.IO заменяет основные файловые функции System.IO и поддерживает имена файлов и папок длиной до 32 767 символов.

Эта библиотека написана на .NET Framework 4.0 и может использоваться как в системах x86 и x64. Ограничения файла и папки стандарта Пространство имен System.IO может работать с файлами, содержащими 260 символов в имя файла и 240 символов в имени папки (обычно MAX_PATH настроен как 260 символов). Обычно вы сталкиваетесь с System.IO.PathTooLongException Ошибка стандартной библиотеки .NET.

...