如何知道两个硬链接是否指向相同的索引页?(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的缓冲区)。