我试图在C#中创建一个简单的“目录/文件复制”控制台应用程序,我需要将所有文件夹和文件(保持原始层次结构)从一个驱动器复制到另一个驱动器,例如从驱动器C:\ Data驱动E:\ Data。
但是,我只希望它将任何新文件或修改过的文件从源复制到目标。 如果目标驱动器上的文件比源驱动器上的文件新,则不会复制。
(问题)
在我拥有的代码中,它将源中的文件“ abc.pdf”与目标中的文件“ xyz.pdf”进行比较,因此即使目标文件是较新的,也将用源文件中的内容覆盖目标文件。我试图弄清楚如何比较源中的“ abc.pdf”和目标中的“ abc.pdf”。
如果我将源和目标向下钻取到特定文件,则此方法有效,但是当我退回到文件夹级别时,即使目标文件是较新的,它也会用源文件覆盖目标文件。
(我的解决方案–没用)
我认为通过在“ foreach”命令之后放置“ if(file.LastWriteTime> destination.LastWriteTime)”,可以比较两个文件夹中的文件,即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));
}
}
}
答案 0 :(得分:0)
您只需在“源”中获取文件数组,然后在“目标”中检查匹配的名称
/// <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;
}
答案 1 :(得分:0)
更新:
我按照上面的建议修改了代码,一切顺利。它完全符合我的预期。
但是,我遇到的问题是在大型文件夹上运行应用程序所花费的时间。 (包含6,000个文件和5个子文件夹)
在一个小文件夹(5个子文件夹中的28个文件)上,只需花费几秒钟即可运行。但是,在较大的文件夹上,只花了35分钟即可处理1300个文件。
解决方案:
下面的代码将执行相同的操作,但速度要快得多。这个新版本在大约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);
}
});
}
}
}