Идентичность путей.
От: Аноним  
Дата: 12.07.11 10:07
Оценка:
Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?

12.07.11 20:53: Перенесено из 'C/C++. Прикладные вопросы'
Re: Идентичность путей.
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.07.11 10:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?


Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.
Маньяк Робокряк колесит по городу
Re[2]: Идентичность путей.
От: BSDыщъх  
Дата: 12.07.11 10:47
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, Аноним, Вы писали:


А>>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?


M>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.


А симлинки как обрабатываются?
Sine vilitate, sine malitiosa mente
Re[2]: Идентичность путей.
От: Аноним  
Дата: 12.07.11 10:55
Оценка:
Здравствуйте, Marty, Вы писали:


M>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.


у записи пути может быть разный синтаксис. Например, в каком-то пути может используется сивол "~", а в каком-то его нет. Тем неменее эти пути могут ссылаться на один файл.
Re: Идентичность путей.
От: BSDыщъх  
Дата: 12.07.11 11:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?


Знаю как это делается для файлов.
GetFileInformationByHandle возвращает в числе прочего
nFileIndexHigh и nFileIndexLow, которые вместе с серийным номером тома однозначно идентифицируют файл.
Работает и с короткими именами и с симлинками-хардлинками.

Как проверить равенство директорий не знаю.
Можно попробовать открыть директорию через CreateFile, для получения хэндла.
Sine vilitate, sine malitiosa mente
Re[3]: Идентичность путей.
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.07.11 11:59
Оценка:
Здравствуйте, BSDыщъх, Вы писали:

BSD>Здравствуйте, Marty, Вы писали:


M>>Здравствуйте, Аноним, Вы писали:


А>>>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?


M>>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.


BSD>А симлинки как обрабатываются?

Никак Потому что есть еще и хардлинки, и без ковыряния всяких inode, по-моему, не разобратся, и вообще, это слишком *nix-specific.
В принципе, можно сначала проверить на islink, или как оно там, сделать readlink и работать уже полученным именем.
Я просто свой подход использую и в *nix, и в винде, в 99% случаев хватает.
Маньяк Робокряк колесит по городу
Re[3]: Идентичность путей.
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.07.11 12:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Marty, Вы писали:



M>>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.


А>у записи пути может быть разный синтаксис. Например, в каком-то пути может используется сивол "~", а в каком-то его нет. Тем неменее эти пути могут ссылаться на один файл.


"~" — ссылка на домашний каталог? На этапе нормализации можно развернуть в реальный путь
Маньяк Робокряк колесит по городу
Re[2]: Идентичность путей.
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.07.11 12:02
Оценка:
Здравствуйте, BSDыщъх, Вы писали:

BSD>Как проверить равенство директорий не знаю.

BSD>Можно попробовать открыть директорию через CreateFile, для получения хэндла.

Нюанс в том, что идентичность путей может проверятся до создания файла. А вообще, мысль интересная.
Маньяк Робокряк колесит по городу
Re[3]: Идентичность путей.
От: Centaur Россия  
Дата: 12.07.11 17:20
Оценка: 1 (1) +1
Здравствуйте, Marty, Вы писали:

M>Нюанс в том, что идентичность путей может проверятся до создания файла. А вообще, мысль интересная.


Когда что-то связанное с файловой системой проверяется до какого-то связанного с файловой системой действия — можно сразу писать багрепорт. Потому что через 200 миллисекунд параллельный процесс сожрёт всё место на диске; или удалит тот файл, существование которого мы только что проверили; или создаст под проверенно незанятым именем в /tmp симлинк на /etc/passwd; или… короче, результат проверки протухнет до того, как мы успеем им воспользоваться.
Re[4]: Идентичность путей.
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.07.11 17:40
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Здравствуйте, Marty, Вы писали:


M>>Нюанс в том, что идентичность путей может проверятся до создания файла. А вообще, мысль интересная.


C>Когда что-то связанное с файловой системой проверяется до какого-то связанного с файловой системой действия — можно сразу писать багрепорт. Потому что через 200 миллисекунд параллельный процесс сожрёт всё место на диске; или удалит тот файл, существование которого мы только что проверили; или создаст под проверенно незанятым именем в /tmp симлинк на /etc/passwd; или… короче, результат проверки протухнет до того, как мы успеем им воспользоваться.


Все верно, это годится для некоторой "предварительной" проверки, я подобные методы использую при обработке пользовательского ввода — в этом случае вероятность параллельного выполнения аналогичного кода довольно низка. Для гарантированного результата лучше сразу создавать/открывать файлы с флагами create new/open existing.

ЗЫ вспомнил один use case — во всяких псевдо-скриптах/конфигах при подключении внешних файлов (типа include), для предотвращения повторного подключения.
Маньяк Робокряк колесит по городу
Re[2]: Идентичность путей.
От: LGB Канада  
Дата: 12.07.11 18:19
Оценка:
Здравствуйте, BSDыщъх, Вы писали:

BSD>Знаю как это делается для файлов.

BSD>GetFileInformationByHandle возвращает в числе прочего
BSD>nFileIndexHigh и nFileIndexLow, которые вместе с серийным номером тома однозначно идентифицируют файл.
BSD>Работает и с короткими именами и с симлинками-хардлинками.

Вот здесь народ о таком же способе говорит, даже код приводится:
http://stackoverflow.com/questions/562701/best-way-to-determine-if-two-path-reference-to-same-file-in-c-c
Re[2]: Идентичность путей.
От: Аноним  
Дата: 12.07.11 18:53
Оценка:
BSD>Знаю как это делается для файлов.
BSD>GetFileInformationByHandle возвращает в числе прочего
BSD>nFileIndexHigh и nFileIndexLow, которые вместе с серийным номером тома однозначно идентифицируют файл.
BSD>Работает и с короткими именами и с симлинками-хардлинками.

но только на NTFS, нет?
Re[3]: Идентичность путей.
От: ononim  
Дата: 12.07.11 19:09
Оценка:
Здравствуйте, Аноним, Вы писали:

BSD>>Знаю как это делается для файлов.

BSD>>GetFileInformationByHandle возвращает в числе прочего
BSD>>nFileIndexHigh и nFileIndexLow, которые вместе с серийным номером тома однозначно идентифицируют файл.
BSD>>Работает и с короткими именами и с симлинками-хардлинками.

А>но только на NTFS, нет?


In the FAT file system, the file ID is generated from the first cluster of the containing directory and the byte offset within the directory of the entry for the file.

(c) MSDN
Как много веселых ребят, и все делают велосипед...
Re[4]: Идентичность путей.
От: Mr.Delphist  
Дата: 14.07.11 18:04
Оценка:
Здравствуйте, Marty, Вы писали:

M>"~" — ссылка на домашний каталог? На этапе нормализации можно развернуть в реальный путь


Нет, тильда означает приведение к 8.3 формату. Т.е. это один и тот же путь
C:\Program Files
C:\PROGRA~1

Самая веселуха начинается, когда до инсталяции винды на винте в корне уже были папки, начинающиеся на "Progra", тогда "C:\Program Files" превратится в "C:\PROGRA~2", "C:\PROGRA~3" etc.
Есть WinAPI-функции по преобразованию между 8.3 и "длинным" форматами, нагуглить труда не составит.
Re[5]: Идентичность путей.
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.07.11 18:48
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Самая веселуха начинается, когда до инсталяции винды на винте в корне уже были папки, начинающиеся на "Progra", тогда "C:\Program Files" превратится в "C:\PROGRA~2", "C:\PROGRA~3" etc.

MD>Есть WinAPI-функции по преобразованию между 8.3 и "длинным" форматами, нагуглить труда не составит.
Я просто протупил, думал это Unix'овый форум
В принципе, также на этапе нормализации можно обрабатывать.
Маньяк Робокряк колесит по городу
Re: Идентичность путей.
От: Аноним  
Дата: 26.07.11 14:29
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?


Вот пример на Delphi:

function OpenDir(const FileName: string): THandle;
begin
Result := CreateFile(PChar(FileName), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
const
FileName1 = 'c:\Program Files (x86)\InstallShield Installation Information';
var
HDir1, HDir2: THandle;
FileName2: string;
R1, R2: TByHandleFileInformation;
begin
FileName2 := ExtractShortPathName(FileName1);
HDir1 := OpenDir(FileName1);
HDir2 := OpenDir(FileName2);
if (HDir1 <> INVALID_HANDLE_VALUE) and (HDir2 <> INVALID_HANDLE_VALUE) then
try
if GetFileInformationByHandle(HDir1, R1) and
GetFileInformationByHandle(HDir2, R2) and
(R1.dwVolumeSerialNumber = R2.dwVolumeSerialNumber) and
(R1.nFileIndexLow = R2.nFileIndexLow) and
(R2.nFileIndexHigh = R2.nFileIndexHigh) then
begin
ShowMessage('The same');
end;
finally
CloseHandle(HDir1);
CloseHandle(HDir2);
end;
end;

Определяет, что каталог один и тот же даже для subst, HardLink, разный сетевой редирект и т.п.
Ограничение (сейчас все менее актуальное): NTFS.

То же можно и для файла, думаю сами справитесь.
Re[2]: Идентичность путей.
От: x64 Россия  
Дата: 26.07.11 20:03
Оценка: 1 (1)
А>Вот пример на Delphi

Во-первых, в этом примере нет никаких ссылок или сетевых путей.
А во-вторых, слабо сделать без непосредственно открытия целевых объектов?
Re[3]: Идентичность путей.
От: Сергей А Россия  
Дата: 27.07.11 16:09
Оценка:
Здравствуйте, x64, Вы писали:

x64>Во-первых, в этом примере нет никаких ссылок или сетевых путей.

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

x64>А во-вторых, слабо сделать без непосредственно открытия целевых объектов?

Я знаю такой способ, который достигает цели, если знаете другой — поделитесь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.