2010-07-18 9 views
6

Я ищу обработку более длинных путей к файлу в приложении Windows.C++ WinAPI: обработка длинных путей/имен файлов

В настоящее время у меня есть текстовое поле (поле редактирования), в котором пользователь может ввести абсолютный путь к файлу. Затем я прочитал, что напечатанный путь к файлу, используя GetWindowText, в строку, объявленной следующим образом: TCHAR FilePath[MAX_PATH];

Очевидно, что здесь я буду полагаться на MAX_PATH константе, которая ограничивает меня до 260 символов. Поэтому, чтобы обрабатывать более длинные имена файлов и путей, я могу просто расширить массив TCHAR следующим образом: TCHAR FilePath[32767];.

Или есть лучший способ? Могу ли я использовать массив переменной длины? (TCHAR FilePath[]; это возможно даже в C++?) Извините, я довольно новичок в этом).

Благодарим вас за продвинутый!


Вот весь фрагмент кода, что я упоминал выше:

TCHAR FilePath[MAX_PATH]; 
ZeroMemory(&FilePath, sizeof(FilePath)); 
GetWindowText(hWndFilePath, FilePath, MAX_PATH); 
+3

В этом и заключается цель «MAX_PATH» - вы не можете иметь пути дольше, чем это. – casablanca

+0

@casablanca Это может быть хорошей идеей объявить его с MAX_PATH + 1 для окончательного символа '\ 0'. – luiscubal

+0

@luiscabal: Я только что проверил [MSDN] (http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maxpath), и похоже, что MAX_PATH включает нулевой терминатор. – casablanca

ответ

11

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

Тем не менее, вы можете использовать более длинные пути - с определенными ограничениями - путем префикса пути с помощью «\\? \». Однако ограничения, используя префикс «\\? \», Как правило, перевешивает пользу:

  1. Там целый ряд Win32 API, которые не делают никакой поддержки пути с этим префиксом (например, LoadLibrary будет всегда терпит неудачу на путь длиной более 260 символов)
  2. Правила Winical Canonicalization не вступают в силу при использовании префикса «\\? \». Например, по умолчанию «/» в путях преобразуется в «\», «.». и ".." преобразуются в ссылки на текущие и родительские каталоги соответственно и так далее: ничто из этого не происходит при использовании префикса \\? \ ".
  3. Просто потому, что вы можете изменить свою программу для поддержки более длинных путей, другие программы могут не открыть файлы, которые вы создали. Это будет так, если в этих других программах также используется префикс «\\? \».

Честно говоря, точка # 2 это настоящий убийца: вы открываете себя для всех видов неприятностей при использовании префикса «\\? \», И вы в основном должны повторно реализовать канонизации Win32 правила самостоятельно если вы идете по этому маршруту.

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

+0

Спасибо за совет. Я думаю, что буду следовать вашей рекомендации! – user353297

+0

Для # 2 обратите внимание, что [GetFullPathNameW] (https://msdn.microsoft.com/library/aa364963) выполняет эту канонизацию для вас и ** не ** ограничивается MAX_PATH, если вы не укажете это как размер буфера. (Префикс пути с \\? \ Только * после * вызова GetFullPathName.) Некоторые оставшиеся оговорки: 1) Пути UNC должны использовать \\? \ UNC \ вместо \\. 2) DOS-устройства, такие как NUL или somedir \ NUL, преобразуются в \\. \ NUL, но \\. \ Не работают повсюду (и \\? \ UNC \. \ NUL - это нечто совсем другое). 3) \\? \ C: \ NUL может создать файл, с которым трудно справиться. – Lexikos

-4

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

5

Это зависит от того, какую программу вы пишете. Моя собственная стратегия, как правило, заключалась в том, чтобы ограничить путь созданием до MAX_PATH в длину, но иметь возможность читать существующие данные из более длинных путей (с использованием префикса \ \ \ "Дин упоминает в своем ответе).Есть исключения из этого, хотя, например, программа резервного копирования должна принимать длинные пути и должна точно воспроизводить то, что было дано в качестве ввода.

В то время как Дин, безусловно, правильно, что Windows не канонизирует более длинные пути для вас, у меня есть , а не, что это вызывает большую озабоченность как общее правило. Это, как правило, не означает написание собственного кода для канонизации пути: обычно это означает, что пользователь вводит пути таким образом, чтобы просто не генерировать такие вещи в первую очередь.