4
어쨌든 C#에서 두 개의 파일 (하드 링크)이 동일한 inode를 가리키는 지 확인 하시겠습니까? 두 개 이상일 경우에 대비하여이 아이 노드의 수를 구하십시오.두 개의 하드 링크가 동일한 inode를 가리키는 지 확인하는 방법? (C#)
어쨌든 C#에서 두 개의 파일 (하드 링크)이 동일한 inode를 가리키는 지 확인 하시겠습니까? 두 개 이상일 경우에 대비하여이 아이 노드의 수를 구하십시오.두 개의 하드 링크가 동일한 inode를 가리키는 지 확인하는 방법? (C#)
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;
}
그들은, 당신은 또 다른 승리 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보다 큰 버퍼를 사용하는 경우를 처리하십시오).