[英]C# - File.Move - Could not find file
File.Move 方法有一個奇怪的問題。 一般來說,我有一個服務,它監視遠程共享上出現的新文件,一旦他們這樣做,它就會通過“ren”cmd function 更改其擴展名並調用其他服務。 然后,此其他服務使用 File.Move 再次更改文件的擴展名。 問題是有時第二個服務失敗並從 System.IO.File.InternalMove 返回錯誤“找不到文件...”,而文件已經存在。
起初我以為可能是網絡連接的問題,但我感覺它經常是由網絡問題引起的。
接下來我開始深入研究 .net 源代碼,發現了一些有趣的東西:
if (!InternalExists(fullSourceFileName))
__Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName);
if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName))
{
__Error.WinIOError();
}
這是 File.InternalMove 方法的一部分,據我了解,該方法返回“找不到文件...”錯誤。 簡而言之,InternalExists 方法是通過檢查 Marshal.GetLastWin32Error() 錯誤和稍后驗證文件上的屬性來檢查文件是否存在。
另外奇怪的是,這種方法似乎使用了某種“hack”(不知道它是否與我的問題有關,但令人擔憂):
// For floppy drives, normally the OS will pop up a dialog saying
// there is no disk in drive A:, please insert one. We don't want that.
// SetErrorMode will let us disable this, but we should set the error
// mode back, since this may have wide-ranging effects.
bool success = false;
int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
try {
success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
}
finally {
Win32Native.SetErrorMode(oldMode);
}
現在有趣的部分:) Class FileInfo 還允許通過 MoveTo() 方法重命名文件。 在這種方法中,“移動”部分如下:
if (!Win32Native.MoveFile(FullPath, fullDestFileName))
__Error.WinIOError();
它與文件 class 中的相同,但它缺少“InternalExists”驗證,所以乍一看它應該可以解決我的問題,但我有點擔心這個缺失的檢查。
有誰知道為什么它是這樣實現的,如果我可以使用 FileInfo.MoveTo 方法? 另外,如果您對問題的原因有任何想法,請分享。 目前我正在質疑,當第一個服務調用“ren”cmd 程序時,新文件還沒有完全重命名,這導致 File.Move 方法失敗,但我還需要驗證它。
我猜這個錯誤實際上是一個權限問題,或者可能是一個鎖定的文件,並且InternalExists
返回的錯誤實際上不是ERROR_FILE_NOT_FOUND
,因為沒有對其進行檢查。
因此,沒有拋出正確的錯誤是一個錯誤。
無論如何,為什么需要存在 Exists 檢查尚不清楚:如果不存在,則在調用MoveFile
時無論如何都會出錯。
我建議你在 GitHub repo 上將此作為一個錯誤提交。 我認為它不太可能得到修復,但至少它會被記錄在案。 如果它因Won't fix
而關閉,您可能需要在文檔中提交拉取請求,並注明這一點。
請注意, 當前代碼實際上是以下代碼,它以稍微不同的方式實現相同的東西。
if (!FileSystem.FileExists(fullSourceFileName))
{
throw new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, fullSourceFileName), fullSourceFileName);
}
FileSystem.MoveFile(fullSourceFileName, fullDestFileName, overwrite);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.