在磁盤之間複製大文件的工具中,我用System.IO.Stream.CopyToAsync替換了System.IO.FileInfo.CopyTo方法中的 。 這允許在拷貝期間更快的拷貝和更好的控制,例如,我可以停止複製。 但是這會造成複製文件的更多碎片化。當我複製數百兆字節的文件時尤其令人討厭。C#I/O異步(copyAsync):如何避免文件碎片?
如何在複製過程中避免磁盤碎片?
使用xcopy命令,/ j開關複製文件而不緩衝。它被推薦用於非常大的文件中TechNet 這似乎的確避免文件碎片(而窗內一個簡單的文件副本10 Explorer支持分段我的檔案!)
沒有緩衝副本似乎比這個相反的方式異步拷貝。或者有沒有辦法異步複製而不緩衝?
這裏它是我當前的代碼異步複製。我讓默認的緩衝區大小爲81920字節,即10 * 1024 *大小(int64)。
我正在使用NTFS文件系統,因此有4096個字節的簇。
編輯:我更新中用SetLength函數的代碼的建議,增加了FileOptions異步在創建destinationStream和修復設置屬性後設定的時間(否則,拋出異常的只讀文件)
int bufferSize = 81920;
try
{
using (FileStream sourceStream = source.OpenRead())
{
// Remove existing file first
if (File.Exists(destinationFullPath))
File.Delete(destinationFullPath);
using (FileStream destinationStream = File.Create(destinationFullPath, bufferSize, FileOptions.Asynchronous))
{
try
{
destinationStream.SetLength(sourceStream.Length); // avoid file fragmentation!
await sourceStream.CopyToAsync(destinationStream, bufferSize, cancellationToken);
}
catch (OperationCanceledException)
{
operationCanceled = true;
}
} // properly disposed after the catch
}
}
catch (IOException e)
{
actionOnException(e, "error copying " + source.FullName);
}
if (operationCanceled)
{
// Remove the partially written file
if (File.Exists(destinationFullPath))
File.Delete(destinationFullPath);
}
else
{
// Copy meta data (attributes and time) from source once the copy is finished
File.SetCreationTimeUtc(destinationFullPath, source.CreationTimeUtc);
File.SetLastWriteTimeUtc(destinationFullPath, source.LastWriteTimeUtc);
File.SetAttributes(destinationFullPath, source.Attributes); // after set time if ReadOnly!
}
我還擔心我的代碼上最後的File.SetAttributes和Time會增加文件碎片。
是否有正確的方法來創建1:1的異步文件副本而沒有任何文件碎片,即要求HDD文件蒸汽只能獲得連續的扇區?
有關文件碎片的其他主題,如How can I limit file fragmentation while working with .NET,建議以較大的塊增加文件大小,但似乎並不直接回答我的問題。
你試過'destinationStream.Length = sourceStream.Length;'就在複製之前? –
好主意,長度只是一個吸氣劑,但SetLength方法完成這項工作。看起來真的要在快速測試中避免分裂! 我在創建destinationStream時也看到了FileOptions。不知道是否異步或WriteThrough可能是一個不錯的選擇 – EricBDev