如何确定两个文件系统URI是否指向同一资源?

时间:2023-01-22 07:21:37

If I have two different file paths, how can I determine whether they point to the same file ?

如果我有两个不同的文件路径,我如何确定它们是否指向同一个文件?

This could be the case, if for instance the user has a network drive attached, which points to some network resource. For example drive S: mapped to \servercrm\SomeFolder.

例如,如果用户连接了网络驱动器,则指向某些网络资源。例如,驱动器S:映射到\ servercrm \ SomeFolder。

Then these paths actually point to the same file:

然后这些路径实际上指向同一个文件:

S:\somefile.dat

And

\\servercrm\SomeFolder\somefile.dat

How can I detect this ? I need to code it so that it works in all scenarios where there might be different ways for a path to point to the same file.

我怎么能发现这个?我需要对其进行编码,以便它可以在所有情况下工作,在这些情况下,路径指向同一文件的方式可能不同。

3 个解决方案

#1


I don't know if there is an easy way to do this directly in C# but you could do an unmanaged call to GetFileInformationByHandle (pinvoke page here) which will return a BY_HANDLE_FILE_INFORMATION structure. This contains three fields which can be combined to uniquely ID a file:

我不知道是否有一种简单的方法可以直接在C#中执行此操作,但您可以对GetFileInformationByHandle(此处为pinvoke页面)进行非托管调用,这将返回BY_HANDLE_FILE_INFORMATION结构。这包含三个字段,可以组合以唯一地标识文件:

dwVolumeSerialNumber: The serial number of the volume that contains a file.

dwVolumeSerialNumber:包含文件的卷的序列号。

...

nFileIndexHigh: The high-order part of a unique identifier that is associated with a file.

nFileIndexHigh:与文件关联的唯一标识符的高阶部分。

nFileIndexLo: The low-order part of a unique identifier that is associated with a file.

nFileIndexLo:与文件关联的唯一标识符的低位部分。

The identifier (low and high parts) and the volume serial number uniquely identify a file on a single computer. To determine whether two open handles represent the same file, combine the identifier and the volume serial number for each file and compare them.

标识符(低和高部分)和卷序列号唯一地标识单个计算机上的文件。要确定两个打开的句柄是否表示同一文件,请合并每个文件的标识符和卷序列号并进行比较。

Note though that this only works if both references are declared from the same machine.

请注意,这仅在两个引用都是从同一台机器声明时才有效。


Edited to add:

编辑添加:

As per this question this may not work for the situation you have since the dwVolumeSerialNumber may be different is the share definitions are different. I'd try it out first though, since I always thought that the volume serial number was drive specific, not path specific. I've never needed to actually prove this though, so I could be (and probably am) wrong.

根据这个问题,这可能不适用于您所拥有的情况,因为dwVolumeSerialNumber可能不同,因为共享定义不同。我首先尝试一下,因为我一直认为卷序列号是特定于驱动器的,而不是路径特定的。我从来不需要真正证明这一点,所以我可能(可能是)错了。

#2


At the very least you could take and compare the MD5 hashes of the combined file contents, file name, and metadata such as CreationTime, LastAccessTime, and LastWriteTime.

至少,您可以比较组合文件内容,文件名和元数据(如CreationTime,LastAccessTime和LastWriteTime)的MD5哈希值。

#3


If you're only worried about local files then you can use the combination of GetFileInformationByHandle and the BY_HANDLE_FILE_INFORMATION structure. Lucian did an excellent blog post on this subject here. The code is in VB.Net but it should be easily convertible to C#

如果您只担心本地文件,则可以使用GetFileInformationByHandle和BY_HANDLE_FILE_INFORMATION结构的组合。 Lucian在这里做了一篇关于这个主题的精彩博文。代码在VB.Net中但它应该可以轻松转换为C#

#1


I don't know if there is an easy way to do this directly in C# but you could do an unmanaged call to GetFileInformationByHandle (pinvoke page here) which will return a BY_HANDLE_FILE_INFORMATION structure. This contains three fields which can be combined to uniquely ID a file:

我不知道是否有一种简单的方法可以直接在C#中执行此操作,但您可以对GetFileInformationByHandle(此处为pinvoke页面)进行非托管调用,这将返回BY_HANDLE_FILE_INFORMATION结构。这包含三个字段,可以组合以唯一地标识文件:

dwVolumeSerialNumber: The serial number of the volume that contains a file.

dwVolumeSerialNumber:包含文件的卷的序列号。

...

nFileIndexHigh: The high-order part of a unique identifier that is associated with a file.

nFileIndexHigh:与文件关联的唯一标识符的高阶部分。

nFileIndexLo: The low-order part of a unique identifier that is associated with a file.

nFileIndexLo:与文件关联的唯一标识符的低位部分。

The identifier (low and high parts) and the volume serial number uniquely identify a file on a single computer. To determine whether two open handles represent the same file, combine the identifier and the volume serial number for each file and compare them.

标识符(低和高部分)和卷序列号唯一地标识单个计算机上的文件。要确定两个打开的句柄是否表示同一文件,请合并每个文件的标识符和卷序列号并进行比较。

Note though that this only works if both references are declared from the same machine.

请注意,这仅在两个引用都是从同一台机器声明时才有效。


Edited to add:

编辑添加:

As per this question this may not work for the situation you have since the dwVolumeSerialNumber may be different is the share definitions are different. I'd try it out first though, since I always thought that the volume serial number was drive specific, not path specific. I've never needed to actually prove this though, so I could be (and probably am) wrong.

根据这个问题,这可能不适用于您所拥有的情况,因为dwVolumeSerialNumber可能不同,因为共享定义不同。我首先尝试一下,因为我一直认为卷序列号是特定于驱动器的,而不是路径特定的。我从来不需要真正证明这一点,所以我可能(可能是)错了。

#2


At the very least you could take and compare the MD5 hashes of the combined file contents, file name, and metadata such as CreationTime, LastAccessTime, and LastWriteTime.

至少,您可以比较组合文件内容,文件名和元数据(如CreationTime,LastAccessTime和LastWriteTime)的MD5哈希值。

#3


If you're only worried about local files then you can use the combination of GetFileInformationByHandle and the BY_HANDLE_FILE_INFORMATION structure. Lucian did an excellent blog post on this subject here. The code is in VB.Net but it should be easily convertible to C#

如果您只担心本地文件,则可以使用GetFileInformationByHandle和BY_HANDLE_FILE_INFORMATION结构的组合。 Lucian在这里做了一篇关于这个主题的精彩博文。代码在VB.Net中但它应该可以轻松转换为C#