我認爲最好的努力是比較音量序列號。 GetFileInformationByHandle()
能夠獲得文件句柄的卷序號。這絕對是RAID /條帶卷的YMMV,所以如果這些適用,我會測試此解決方案的性能。它確實工作的交界點。
的的DllImport它是
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetFileInformationByHandle(
IntPtr hFile,
out BY_HANDLE_FILE_INFORMATION lpFileInformation);
我們還需要一種方式來獲得適當的文件句柄來使用。由於我們正在處理潛在目標,如果我們假設目標目錄已經存在,我們可以使用CreateFile()
來獲取目錄句柄。
爲CreateFile()
,則是的DllImport
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CreateFile(
[MarshalAs(UnmanagedType.LPTStr)] string filename,
[MarshalAs(UnmanagedType.U4)] FileAccess access,
[MarshalAs(UnmanagedType.U4)] FileShare share,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
[MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
IntPtr templateFile);
我們還需要CloseHandle()
,
[DllImport("kernel32.dll", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
有了所有這些片段,創建一個返回true的包裝方法,如果卷序列號提供的路徑匹配。這顯然是有道理的拋出更具體的異常,但爲了簡潔起見:
static bool SameVolume(string src, string dest)
{
IntPtr srcHandle = IntPtr.Zero, destHandle = IntPtr.Zero;
try
{
srcHandle = CreateFile(src, FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero,
FileMode.Open, (FileAttributes) 0x02000000, IntPtr.Zero);
destHandle = CreateFile(dest, FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero,
FileMode.Open, (FileAttributes) 0x02000000, IntPtr.Zero);
var srcInfo = new BY_HANDLE_FILE_INFORMATION();
var destInfo = new BY_HANDLE_FILE_INFORMATION();
if (!GetFileInformationByHandle(srcHandle, out srcInfo))
{
throw new Exception(Marshal.GetLastWin32Error().ToString());
}
if (!GetFileInformationByHandle(destHandle, out destInfo))
{
throw new Exception(Marshal.GetLastWin32Error().ToString());
}
return srcInfo.VolumeSerialNumber == destInfo.VolumeSerialNumber;
}
finally
{
if (srcHandle != IntPtr.Zero)
{
CloseHandle(srcHandle);
}
if (destHandle != IntPtr.Zero)
{
CloseHandle(destHandle);
}
}
}
或者,你可以只使用
Task.Run(() => File.Move(x))
或另一個異步結構得到這個無鎖起來做應用程序的界面。我看不出有什麼問題。
驅動器號不一定會工作(我認爲),條紋卷或RAID呢? - 試圖想出想法,但是想到這個想法 – jdphenix
@jdphenix是的,好的,除了交接點外,這是另一個原因,不要這樣做。 – Casey
Windows或* nix?或者需要一些便攜式? – jdphenix