如何知道两个硬链接是否指向相同的索引页?(c#)

本文关键字:索引 是否 何知道 两个 链接 | 更新日期: 2023-09-27 18:17:37

无论如何检查,在c#中,这两个文件(硬链接)指向同一个索引节点?同时得到这个索引节点的计数,以防有超过两个…div ?

您可以使用GetFileInformationByHandle函数获得指向该节点的硬链接的计数。例如:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetFileInformationByHandle(
    SafeFileHandle hFile,
    out BY_HANDLE_FILE_INFORMATION lpFileInformation
);
[StructLayout(LayoutKind.Sequential)]
struct BY_HANDLE_FILE_INFORMATION {
    public uint FileAttributes;
    public FILETIME CreationTime;
    public FILETIME LastAccessTime;
    public FILETIME LastWriteTime;
    public uint VolumeSerialNumber;
    public uint FileSizeHigh;
    public uint FileSizeLow;
    public uint NumberOfLinks;
    public uint FileIndexHigh;
    public uint FileIndexLow;
}
// then in another place
using (var fs = File.OpenRead("path to your file")) {                
    BY_HANDLE_FILE_INFORMATION info;
    GetFileInformationByHandle(fs.SafeFileHandle, out info);
    var numberOfLinks = info.NumberOfLinks;
}
要获取它们指向的文件,您将需要另一个win api函数:FindFirstFileNameW和FineNextFileNameW。像这样使用它们:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern IntPtr FindFirstFileNameW(
       string lpFileName,
       uint dwFlags,
       ref uint stringLength,
       StringBuilder fileName);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool FindNextFileNameW(
        IntPtr hFindStream,
        ref uint stringLength,
        StringBuilder fileName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FindClose(IntPtr fFindHandle);
public static string[] GetFileHardLinks(string filePath) {
    // first get drive letter
    var drive = new DriveInfo(Path.GetPathRoot(filePath));
    var result = new List<string>();
    // buffer for return value
    var sb = new StringBuilder(256);
    // length of buffer
    uint sbLength = 256;
    // third argument contains reference to buffer length (buffer is StringBuilder). 
    // it's a reference because if it's too small, call returns an error and will put required length there instead
    IntPtr findHandle = FindFirstFileNameW(filePath, 0, ref sbLength, sb);
    // returns -1 on error
    if (findHandle.ToInt64() != -1) {
        do {
            // combine the result with drive letter (it comes without it)
            result.Add(Path.Combine(drive.RootDirectory.FullName, sb.ToString().TrimStart(new [] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar})));
            sb.Clear();
            sbLength = 256;
            // and repeat
        } while (FindNextFileNameW(findHandle, ref sbLength, sb));
        FindClose(findHandle);
        return result.ToArray();
    }
    return null;
}

这段代码可能还不能用于生产,所以要小心。但它至少给了你一个概念。如果您要使用它-仔细阅读这些函数在错误时返回的内容并采取相应的措施(例如,处理缓冲区长度不足的情况,或者只是使用大于256的缓冲区)。

如何知道两个硬链接是否指向相同的索引页?(c#)