Здравствуйте, Marty, Вы писали:
M>Нюанс в том, что идентичность путей может проверятся до создания файла. А вообще, мысль интересная.
Когда что-то связанное с файловой системой проверяется до какого-то связанного с файловой системой действия — можно сразу писать багрепорт. Потому что через 200 миллисекунд параллельный процесс сожрёт всё место на диске; или удалит тот файл, существование которого мы только что проверили; или создаст под проверенно незанятым именем в /tmp симлинк на /etc/passwd; или… короче, результат проверки протухнет до того, как мы успеем им воспользоваться.
Здравствуйте, Аноним, Вы писали:
А>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через 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.
То же можно и для файла, думаю сами справитесь.
Идентичность путей.
От:
Аноним
Дата:
12.07.11 10:07
Оценка:
Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?
12.07.11 20:53: Перенесено из 'C/C++. Прикладные вопросы'
Здравствуйте, Аноним, Вы писали:
А>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?
Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, Аноним, Вы писали:
А>>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?
M>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.
А симлинки как обрабатываются?
Sine vilitate, sine malitiosa mente
Re[2]: Идентичность путей.
От:
Аноним
Дата:
12.07.11 10:55
Оценка:
Здравствуйте, Marty, Вы писали:
M>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.
у записи пути может быть разный синтаксис. Например, в каком-то пути может используется сивол "~", а в каком-то его нет. Тем неменее эти пути могут ссылаться на один файл.
Здравствуйте, Аноним, Вы писали:
А>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?
Знаю как это делается для файлов.
GetFileInformationByHandle возвращает в числе прочего
nFileIndexHigh и nFileIndexLow, которые вместе с серийным номером тома однозначно идентифицируют файл.
Работает и с короткими именами и с симлинками-хардлинками.
Как проверить равенство директорий не знаю.
Можно попробовать открыть директорию через CreateFile, для получения хэндла.
Здравствуйте, BSDыщъх, Вы писали:
BSD>Здравствуйте, Marty, Вы писали:
M>>Здравствуйте, Аноним, Вы писали:
А>>>Две строки содержат пути к файлам/папкам. Как определить что эти пути ссылаются на однин и тотже файл/паку? Возможно ли это сделать через win api?
M>>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.
BSD>А симлинки как обрабатываются?
Никак Потому что есть еще и хардлинки, и без ковыряния всяких inode, по-моему, не разобратся, и вообще, это слишком *nix-specific.
В принципе, можно сначала проверить на islink, или как оно там, сделать readlink и работать уже полученным именем.
Я просто свой подход использую и в *nix, и в винде, в 99% случаев хватает.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Marty, Вы писали:
M>>Я сам делал. Разбиваем путь на части, схлопываем '.' и '..', заменяем '/' на '\', затем сравниваем без учета регистра.
А>у записи пути может быть разный синтаксис. Например, в каком-то пути может используется сивол "~", а в каком-то его нет. Тем неменее эти пути могут ссылаться на один файл.
"~" — ссылка на домашний каталог? На этапе нормализации можно развернуть в реальный путь
Здравствуйте, BSDыщъх, Вы писали:
BSD>Как проверить равенство директорий не знаю. BSD>Можно попробовать открыть директорию через CreateFile, для получения хэндла.
Нюанс в том, что идентичность путей может проверятся до создания файла. А вообще, мысль интересная.
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, Marty, Вы писали:
M>>Нюанс в том, что идентичность путей может проверятся до создания файла. А вообще, мысль интересная.
C>Когда что-то связанное с файловой системой проверяется до какого-то связанного с файловой системой действия — можно сразу писать багрепорт. Потому что через 200 миллисекунд параллельный процесс сожрёт всё место на диске; или удалит тот файл, существование которого мы только что проверили; или создаст под проверенно незанятым именем в /tmp симлинк на /etc/passwd; или… короче, результат проверки протухнет до того, как мы успеем им воспользоваться.
Все верно, это годится для некоторой "предварительной" проверки, я подобные методы использую при обработке пользовательского ввода — в этом случае вероятность параллельного выполнения аналогичного кода довольно низка. Для гарантированного результата лучше сразу создавать/открывать файлы с флагами create new/open existing.
ЗЫ вспомнил один use case — во всяких псевдо-скриптах/конфигах при подключении внешних файлов (типа include), для предотвращения повторного подключения.
Здравствуйте, BSDыщъх, Вы писали:
BSD>Знаю как это делается для файлов. BSD>GetFileInformationByHandle возвращает в числе прочего BSD>nFileIndexHigh и nFileIndexLow, которые вместе с серийным номером тома однозначно идентифицируют файл. BSD>Работает и с короткими именами и с симлинками-хардлинками.
BSD>Знаю как это делается для файлов. BSD>GetFileInformationByHandle возвращает в числе прочего BSD>nFileIndexHigh и nFileIndexLow, которые вместе с серийным номером тома однозначно идентифицируют файл. BSD>Работает и с короткими именами и с симлинками-хардлинками.
Здравствуйте, Аноним, Вы писали:
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
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Marty, Вы писали:
M>"~" — ссылка на домашний каталог? На этапе нормализации можно развернуть в реальный путь
Нет, тильда означает приведение к 8.3 формату. Т.е. это один и тот же путь
C:\Program Files
C:\PROGRA~1
Самая веселуха начинается, когда до инсталяции винды на винте в корне уже были папки, начинающиеся на "Progra", тогда "C:\Program Files" превратится в "C:\PROGRA~2", "C:\PROGRA~3" etc.
Есть WinAPI-функции по преобразованию между 8.3 и "длинным" форматами, нагуглить труда не составит.
Здравствуйте, Mr.Delphist, Вы писали:
MD>Самая веселуха начинается, когда до инсталяции винды на винте в корне уже были папки, начинающиеся на "Progra", тогда "C:\Program Files" превратится в "C:\PROGRA~2", "C:\PROGRA~3" etc. MD>Есть WinAPI-функции по преобразованию между 8.3 и "длинным" форматами, нагуглить труда не составит.
Я просто протупил, думал это Unix'овый форум
В принципе, также на этапе нормализации можно обрабатывать.
Здравствуйте, x64, Вы писали:
x64>Во-первых, в этом примере нет никаких ссылок или сетевых путей.
Это будет работать и для ссылок и для сетевых путей — главное идея и работающий пример.
x64>А во-вторых, слабо сделать без непосредственно открытия целевых объектов?
Я знаю такой способ, который достигает цели, если знаете другой — поделитесь.