La meilleure façon de déterminer si deux chemin d'accès de référence au même fichier dans Windows?
Comment pourrais-je comparer 2 chaînes pour déterminer si elles visent le même chemin dans Win32 l'aide de C/C++?
Bien que cela va gérer un grand nombre de cas, il manque certaines choses:
_tcsicmp(szPath1, szPath2) == 0
Par exemple:
- barres obliques /barres obliques inverses
- relatif /absolu chemins.
[Modifier] Titre changé pour correspondre à un existant C# question.
Des liens en dur trop?
OriginalL'auteur Adam Tegen | 2009-02-18
Vous devez vous connecter pour publier un commentaire.
Ouvrez les deux fichiers avec
CreateFile
, appelGetFileInformationByHandle
pour les deux, et de les comparerdwVolumeSerialNumber
,nFileIndexLow
,nFileIndexHigh
. Si tous les trois sont égaux ils pointent vers le même fichier:GetFileInformationByHandle
functionBY_HANDLE_FILE_INFORMATION
de la StructureL'2016 documentation de la BY_HANDLE_FILE_INFORMATION structure dit "Le 64 bits identificateur dans cette structure n'est pas garantie unique sur les ReFS." et "Pour récupérer la 128 bits de l'identificateur de fichier utiliser le GetFileInformationByHandleEx fonction avec FileIdInfo pour récupérer le FILE_ID_INFO structure." Cette approche fonctionne sur Windows 8 et plus récentes. Il nécessite l'option de compilation -D_WIN32_WINNT=_WIN32_WINNT_WIN8.
OriginalL'auteur MSN
Voir cette question: La meilleure façon de déterminer si deux chemin d'accès de référence au même fichier en C#
La question est à propos de C#, mais la réponse est juste de l'API Win32 appel
GetFileInformationByHandle
.OriginalL'auteur sth
utiliser le GetFullPathName de kernel32.dll, cela vous donne le chemin absolu du fichier. Puis le comparer à un autre chemin que vous avez à l'aide d'une simple chaîne de comparer
edit: code
le code ci-dessus va imprimer le même chemin d'accès pour tous les trois chemin de représentations.. vous pouvez faire une recherche insensible à la casse après que
oui, mais GetFullPathName va vous donner le chemin absolu vers le même fichier.. donc il doit être la même..
Des liens en dur de permettre un fichier unique d'avoir deux noms différents. Et oui, ceux d'entre vous qui ne connaissent que suffisant pour être un danger pour vous et pour les autres, Windows prend en charge des liens en dur.
Est venu de dire exactement que. Des liens en dur sont les démons de l'aire de jeux. Vous avez besoin de plus qu'un chemin, afin de déterminer la monotonie.
Cela ne semble pas non plus en compte les répertoires avec des barres obliques (c'est à dire c:\blah vs c:\blah).
OriginalL'auteur user65157
Une simple comparaison de chaînes n'est pas suffisant pour comparer les chemins de l'égalité. Sous windows, il est tout à fait possible pour c:\foo\bar.txt et c:\temp\bar.txt au point exactement le même fichier via des liens symboliques et matériels dans le système de fichiers.
Comparant les chemins correctement essentiellement vous oblige à ouvrir les deux fichiers et de comparer le faible niveau de la poignée de l'information. Toute autre méthode va avoir feuilletée résultats.
Découvrez cet excellent post Lucian faites sur le sujet. Le code est en VB, mais c'est assez traduisibles en C/C++ comme il PInvoke avais la plupart des méthodes.
http://blogs.msdn.com/vbteam/archive/2008/09/22/to-compare-two-filenames-lucian-wischik.aspx
OriginalL'auteur JaredPar
Si vous avez accès à des bibliothèques Boost, essayez
http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#equivalent
Résumer de la documentation: Retourne
true
si lepath
objets résoudre à le même système de fichiers de l'entité, d'autrefalse
.Vrai. On pourrait regarder le code source et l'utiliser comme un guide pour la mise en œuvre de cette petite pièce sur votre propre.
OriginalL'auteur aldo
Système de fichiers de la bibliothèque
Depuis C++17, vous pouvez utiliser le standard du système de fichiers de la bibliothèque. L'inclure à l'aide de
#include <filesystem>
. Vous pouvez y accéder même dans les anciennes versions de C++, voir note de bas de page.La fonction que vous cherchez est
equivalent
, sous l'espace de nomsstd::filesystem
:Résumer de la la documentation: cette fonction prend deux chemins que les paramètres et renvoie true si elles font référence au même fichier ou d'un répertoire, false sinon. Il y a aussi un
noexcept
surcharge qui prend un troisième paramètre: unstd::error_code
dans lequel enregistrer toute erreur éventuelle.Exemple
De sortie:
À l'aide du système de fichiers avant le C++17
Pour utiliser cette bibliothèque dans les versions antérieures à C++17 vous devez activer expérimentale fonctionnalités de langage de votre compilateur et inclure la bibliothèque de cette manière:
#include <experimental/filesystem>
. Vous pouvez ensuite utiliser ses fonctions en vertu de l'espace de nomsstd::experimental::filesystem
. Veuillez noter que le expérimentales système de fichiers de la bibliothèque peuvent différer du C++17. Consultez la documentation ici.Par exemple:
OriginalL'auteur Stypox
Ce que vous devez faire est d'obtenir le chemin canonique.
Pour chaque chemin que vous avez demandez le système de fichiers pour convertir à une représentation canonique du chemin ou de vous donner un identifiant l'identifie de manière unique le fichier (comme l'iNode).
Puis de comparer les canonique chemin d'accès ou l'identifiant unique.
Note:
N'essayez pas de comprendre la forme conique de la chemin vous-même le Système de Fichiers peut faire des choses avec les liens symboliques, etc qui ne sont pas facilement traitable, sauf si vous êtes très familier avec le système de fichiers.
OriginalL'auteur Martin York
Basée sur les réponses sur GetFileInformationByHandle(), voici le code.
Remarque: Cela ne fonctionne que si le fichier existe déjà...
Et votre point de vue? Vous ne pouvez même pas appeler
GetFileInformationByHandle
sauf si le fichier est ouvert, et que ce code n'est pas près non plus de la poignée entre les appels.Bonne question. J'ai écrit ce commentaire il y a si longtemps que je ne me souviens plus de ce que j'avais à l'esprit.
Ce que je dois dire, c'est que la valeur de retour de IsSameFile (bResult) devient obsolète avant même IsSameFile retourne.
L'2016 documentation de la BY_HANDLE_FILE_INFORMATION structure dit "Le 64 bits identificateur dans cette structure n'est pas garantie unique sur les ReFS." et "Pour récupérer la 128 bits de l'identificateur de fichier utiliser le GetFileInformationByHandleEx fonction avec FileIdInfo pour récupérer le FILE_ID_INFO structure." Cette approche fonctionne sur Windows 8 et plus récentes. Il nécessite l'option de compilation -D_WIN32_WINNT=_WIN32_WINNT_WIN8.
OriginalL'auteur Adam Tegen
Comparant les chaînes de chemin d'accès ne sera pas produire des résultats précis, si vous vous référez à l'UNC ou Canonique chemins (c'est à dire rien d'autre qu'un chemin d'accès local).
shlwapi.h a certains Chemin Des Fonctions qui peuvent être utiles pour déterminer si vos chemins d'accès sont les mêmes.
Il contient des fonctions comme PathIsRoot qui pourrait être utilisé dans une fonction de plus grande ampleur.
OriginalL'auteur user62572
Ouvrir les deux fichiers et de les utiliser
GetFinalPathNameByHandle()
contre laHANDLE
s. Ensuite, comparez les chemins.OriginalL'auteur CodeAngry
Si les fichiers existent et vous pouvez traiter avec le potentiel condition de course et les performances de l'ouverture de fichiers, une solution imparfaite qui devrait fonctionner sur n'importe quel plate-forme de l'ouverture d'un fichier pour l'écriture par elle-même, fermez, puis ouvrez-le pour écrire à nouveau après l'ouverture de l'autre fichier pour l'écriture. Depuis l'accès en écriture ne devraient être autorisés à être exclusif, si vous avez été en mesure d'ouvrir le premier fichier pour l'écriture de la première fois mais pas la deuxième fois, alors les chances sont vous avez bloqué votre propre demande lorsque vous avez essayé d'ouvrir les deux fichiers.
(les chances sont, bien entendu, aussi qu'une autre partie du système a l'un de vos fichiers ouverts)
OriginalL'auteur Matthew