[英]Copy only new or modified files/directories in C#
我正在嘗試在 C# 中創建一個簡單的“目錄/文件復制”控制台應用程序。我需要的是將所有文件夾和文件(保持原始層次結構)從一個驅動器復制到另一個驅動器,例如從驅動器 C:\\Data 復制到驅動器 E :\\數據。
但是,我只希望它將任何 NEW 或 MODIFIED 文件從源復制到目標。 如果目標驅動器上的文件比源驅動器上的文件新,則不會復制。
(問題)
在我擁有的代碼中,它將源中的文件“abc.pdf”與目標中的文件“xyz.pdf”進行比較,因此即使目標文件較新,也會用源中的任何內容覆蓋目標文件。 我想弄清楚如何將源中的“abc.pdf”與目標中的“abc.pdf”進行比較。
如果我將源和目標向下鑽取到特定文件,這會起作用,但是當我返回到文件夾級別時,它會用源文件覆蓋目標文件,即使目標文件較新。
(我的解決方案 - 沒有用)
我想通過將“if (file.LastWriteTime > destination.LastWriteTime)”放在“foreach”命令之后,它會比較兩個文件夾中的文件,File1 源文件和 File1 目標文件,但事實並非如此。
似乎我在“FileInfo[]”、“foreach”或“if”語句中遺漏了一些東西來進行一對一的比較。 我想可能是對“Path.Combine”語句或“SearchOption.AllDirectories”的一些引用,但我不確定。
有什么建議?
正如您從我的基本代碼示例中看到的,我是 C# 新手,所以請用簡單的術語回答您的問題。
謝謝你。
這是我嘗試過的代碼,但它不起作用。
class Copy
{
public static void CopyDirectory(DirectoryInfo source, DirectoryInfo destination)
{
if (!destination.Exists)
{
destination.Create();
}
// Copy files.
FileInfo[] files = source.GetFiles();
FileInfo[] destFiles = destination.GetFiles();
foreach (FileInfo file in files)
foreach (FileInfo fileD in destFiles)
// Copy only modified files
if (file.LastWriteTime > fileD.LastWriteTime)
{
file.CopyTo(Path.Combine(destination.FullName,
file.Name), true);
}
// Copy all new files
else
if (!fileD.Exists)
{
file.CopyTo(Path.Combine(destination.FullName, file.Name), true);
}
// Process subdirectories.
DirectoryInfo[] dirs = source.GetDirectories();
foreach (DirectoryInfo dir in dirs)
{
// Get destination directory.
string destinationDir = Path.Combine(destination.FullName, dir.Name);
// Call CopyDirectory() recursively.
CopyDirectory(dir, new DirectoryInfo(destinationDir));
}
}
}
您可以只獲取“源”中的文件數組並檢查“目標”中的匹配名稱
/// <summary>
/// checks whether the target file needs an update (if it doesn't exist: it needs one)
/// </summary>
public static bool NeedsUpdate(FileInfo localFile, DirectoryInfo localDir, DirectoryInfo backUpDir)
{
bool needsUpdate = false;
if (!File.Exists(Path.Combine(backUpDir.FullName, localFile.Name)))
{
needsUpdate = true;
}
else
{
FileInfo backUpFile = new FileInfo(Path.Combine(backUpDir.FullName, localFile.Name));
DateTime lastBackUp = backUpFile.LastWriteTimeUtc;
DateTime lastChange = localFile.LastWriteTimeUtc;
if (lastChange != lastBackUp)
{
needsUpdate = true;
}
else
{/*no change*/}
}
return needsUpdate;
}
更新:
我用上面的建議修改了我的代碼,一切順利。 它完全符合我的預期。
但是,我遇到的問題是在大文件夾上運行應用程序所花費的時間。 (包含 6,000 個文件和 5 個子文件夾)
在一個小文件夾上,(5 個子文件夾中的 28 個文件)運行只需要幾秒鍾。 但是,在較大的文件夾中,僅處理 1,300 個文件需要 35 分鍾。
解決方案:
下面的代碼將做同樣的事情,但速度要快得多。 這個新版本在大約 10 秒內處理了 6,000 個文件。 它在大約 1 分 50 秒內處理了 40,000 個文件。
這個新代碼做什么(和不做什么)
如果目標文件夾為空,則將所有內容從源復制到目標。
如果目標具有與源相同的部分或全部文件/文件夾,則比較並將任何新的或修改過的文件從源復制到目標。
如果目標文件比源文件新,請不要復制。
所以,這是實現它的代碼。 享受和分享。
感謝所有幫助我更好地理解這一點的人。
using System;
using System.IO;
namespace VSU1vFileCopy
{
class Program
{
static void Main(string[] args)
{
const string Src_FOLDER = @"C:\Data";
const string Dest_FOLDER = @"E:\Data";
string[] originalFiles = Directory.GetFiles(Src_FOLDER, "*", SearchOption.AllDirectories);
Array.ForEach(originalFiles, (originalFileLocation) =>
{
FileInfo originalFile = new FileInfo(originalFileLocation);
FileInfo destFile = new FileInfo(originalFileLocation.Replace(Src_FOLDER, Dest_FOLDER));
if (destFile.Exists)
{
if (originalFile.Length > destFile.Length)
{
originalFile.CopyTo(destFile.FullName, true);
}
}
else
{
Directory.CreateDirectory(destFile.DirectoryName);
originalFile.CopyTo(destFile.FullName, false);
}
});
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.