Mir ist klar, dass dies ein alter Beitrag ist, aber alle Antworten basieren letztendlich auf einem Textvergleich zweier Namen. Der Versuch, zwei "normalisierte" Namen zu erhalten, die die Vielzahl möglicher Verweismöglichkeiten auf dasselbe Dateiobjekt berücksichtigen, ist nahezu unmöglich. Es gibt Probleme wie: Junctions, symbolische Links, Netzwerkdateifreigaben (die auf unterschiedliche Weise auf dasselbe Dateiobjekt verweisen ) usw. usw. Tatsächlich führt jede einzelne Antwort oben, mit Ausnahme von Igor Korkhovs, absolut zu falschen Ergebnissen bestimmte Umstände (z. B. Kreuzungen, symbolische Links, Verzeichnislinks usw.)
In der Frage wurde ausdrücklich gefordert, dass für die Lösung keine E / A erforderlich sind. Wenn Sie sich jedoch mit vernetzten Pfaden befassen möchten, müssen Sie unbedingt E / A ausführen: Es gibt Fälle, in denen es einfach nicht möglich ist, anhand einer lokalen Pfadzeichenfolge zu bestimmen Manipulation, ob zwei Dateiverweise auf dieselbe physische Datei verweisen. (Dies kann wie folgt leicht verstanden werden. Angenommen, ein Dateiserver verfügt über eine Windows-Verzeichnisverbindung an einer Stelle innerhalb eines gemeinsam genutzten Teilbaums. In diesem Fall kann auf eine Datei entweder direkt oder über die Verbindung verwiesen werden. Die Verbindung befindet sich jedoch auf dem Dateiserver. Daher ist es für einen Client einfach unmöglich, allein durch lokale Informationen festzustellen, dass sich die beiden referenzierenden Dateinamen auf dieselbe physische Datei beziehen: Die Informationen stehen dem Client einfach nicht lokal zur Verfügung.
Die folgende Lösung führt einige E / A-Vorgänge aus, obwohl sie sehr minimal sind, bestimmt jedoch korrekt, ob zwei Dateisystemreferenzen semantisch identisch sind, dh auf dasselbe Dateiobjekt verweisen. (Wenn sich keine der Dateispezifikationen auf ein gültiges Dateiobjekt bezieht, sind alle Wetten deaktiviert):
public static bool AreFileSystemObjectsEqual(string dirName1, string dirName2)
{
bool bRet = string.Equals(dirName1, dirName2, StringComparison.OrdinalIgnoreCase);
if (!bRet)
{
using (SafeFileHandle directoryHandle1 = GetFileHandle(dirName1), directoryHandle2 = GetFileHandle(dirName2))
{
BY_HANDLE_FILE_INFORMATION? objectFileInfo1 = GetFileInfo(directoryHandle1);
BY_HANDLE_FILE_INFORMATION? objectFileInfo2 = GetFileInfo(directoryHandle2);
bRet = objectFileInfo1 != null
&& objectFileInfo2 != null
&& (objectFileInfo1.Value.FileIndexHigh == objectFileInfo2.Value.FileIndexHigh)
&& (objectFileInfo1.Value.FileIndexLow == objectFileInfo2.Value.FileIndexLow)
&& (objectFileInfo1.Value.VolumeSerialNumber == objectFileInfo2.Value.VolumeSerialNumber);
}
}
return bRet;
}
Die Idee dazu kam von einer Antwort von Warren Stevens in einer ähnlichen Frage, die ich auf SuperUser gepostet habe: https://superuser.com/a/881966/241981