Подтвердить что ты не робот

Нормализовать путь к файлу с помощью WinAPI

Возможный дубликат:
Лучший способ определить, является ли ссылка двух ссылок на один и тот же файл на C/С++

Учитывая две строки пути к файлу с потенциально различной оболочкой и косой чертой ('\' vs '/'), есть быстрый способ (который не включает в себя запись моей собственной функции), чтобы нормализовать оба пути к одной и той же форме или чтобы проверить их эквивалентность?

Я ограничен WinAPI и стандартным С++. Все файлы локальные.

4b9b3361

Ответ 1

В зависимости от того, могут ли пути быть относительными или содержать "..", или точки соединения, или пути UNC, это может быть сложнее, чем вы думаете. Лучшим способом может быть использование функции GetFileInformationByHandle(), как в этом ответе.

Изменить: Я согласен с комментарием RBerteig, что это может быть трудно сделать, если пути не указывают на локальный файл. Любой комментарий о том, как безопасно обрабатывать этот случай, будет с благодарностью.

Ответ 3

Я нашел запись в блоге с самой тщательной, даже сложной функцией, которую я когда-либо видел, чтобы решить эту проблему. Он обрабатывает все, даже ужасные угловые случаи, такие как V:foo.txt, где вы использовали команду subst для сопоставления V: - Z:, но вы уже использовали subst для сопоставления Z: с другим диском; он перебирается до тех пор, пока все команды subst не разматываются. URL:

http://pdh11.blogspot.com/2009/05/pathcanonicalize-versus-what-it-says-on.html

Мой проект - чистый C-код, и эта функция - С++. Я начал переводить его, но потом я понял, что могу получить нормализованный путь, который мне нужен, с помощью одного вызова функции: GetLongPathName(). Это не будет обрабатывать ужасные угловые случаи, но оно справляется с моими непосредственными потребностями.

Я обнаружил, что GetLongPathName("foo.txt") просто возвращает foo.txt, но просто добавив ./ к имени файла, я получил расширение в нормализованную форму:

GetLongPathName("./foo.txt"), если выполняется в каталоге C:\Users\steveha, возвращает C:\Users\steveha\foo.txt.

Итак, в псевдокоде:

если второй char имени пути: ':' или первый char есть '/' или '\', просто вызовите GetLongPathName() else, скопируйте "./" в временный буфер, затем скопируйте имя файла в temp buffer + 2, чтобы получить копию имени файла, добавленного с помощью "./", а затем вызвать GetLongPathName().

Ответ 4

Есть странные случаи. Например, "c:\windows..\data\myfile.txt" совпадает с "c:\data.\Myfile.txt" и "c:\data\myfile.txt". У вас может быть любое количество "\. \" И "\.. \". Вы можете заглянуть в функцию Windows API GetFullPathName. Это может сделать канонизацию для вас.