在本地 c# 同步两个文件夹中的操作
Sync actions in two folders locally c#
我正在学习 C#,我有一个任务:
同步两个目录的内容。
给定两个目录的路径 - dir1 和 dir2,那么 dir2 应该与目录 1 同步:
- 如果一个文件存在于目录 1 而目录 2 中不存在,则应该复制它
-如果一个文件存在于dir1和dir2中,但内容被改变,那么dir1中的文件应该覆盖dir2中的文件
-如果文件存在于 dir2 但不在 dir1 中,则应将其删除
注意:文件可能非常大
-dir1 可以有嵌套文件夹
提示:
-读写文件异步
-哈希文件内容并比较哈希值而不是内容
我有一些关于如何做到这一点的逻辑,但我不知道如何实施it.I 用谷歌搜索整个互联网以找到一个起点,但没有成功。
我从这个开始:
using System.Security.Cryptography;
class Program
{
static void Main(string[] args)
{
string sourcePath = @"C:\Users\artio\Desktop\FASassignment\root\dir1";
string destinationPath = @"C:\Users\artio\Desktop\FASassignment\root\dir2";
string[] dirsInSourcePath = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
string[] dirsInDestinationPath = Directory.GetDirectories(destinationPath, "*", SearchOption.AllDirectories);
var filesInSourcePath = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
var filesInDestinationPath = Directory.GetFiles(destinationPath,"*",SearchOption.AllDirectories);
//Directories in source Path
foreach (string dir in dirsInSourcePath)
{
Console.WriteLine("sourcePath:{0}", dir);
Directory.CreateDirectory(dir);
}
//Directories in destination path
foreach (string dir in dirsInDestinationPath)
{
Console.WriteLine("destinationPath:{0} ", dir);
}
//Files in source path
foreach (var file in filesInSourcePath)
{
Console.WriteLine(Path.GetFileName(file));
}
//Files in destination path
foreach (var file in filesInDestinationPath)
{
Console.WriteLine(Path.GetFileName(file));
}
}
}
据我了解,我应该检查dir1中是否有一些文件夹和文件,如果是,则将它们复制到文件夹2中,依此类推,但是如何做到这一点?我已经焦头烂额两天了,不知道..请帮忙。
编辑:对于第一点和第二点,我找到了解决方案。 :
public static void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders)
{
try
{
/*if (!sourceFolder.EndsWith(@"\")) { sourceFolder += @"\"; }
if (!destinationFolder.EndsWith(@"\")) { destinationFolder += @"\"; }*/
var exDir = sourceFolder;
var dir = new DirectoryInfo(exDir);
SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so))
{
FileInfo srcFile = new FileInfo(sourceFile);
string srcFileName = srcFile.Name;
// Create a destination that matches the source structure
FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, ""));
if (!Directory.Exists(destFile.DirectoryName) && createFolders)
{
Directory.CreateDirectory(destFile.DirectoryName);
}
if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists)
{
File.Copy(srcFile.FullName, destFile.FullName, true);
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace);
}
}
不完美,但works.How这个功能应该改进:添加异步复制,并比较文件的哈希值,不要再次复制相同的文件。怎么做?
所以,经过一段时间的更多研究,我想出了这个解决方案:
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
string sourcePath = @"C:\Users\artio\Desktop\FASassignment\root\dir1";
string destinationPath = @"C:\Users\artio\Desktop\FASassignment\root\dir2";
var source = new DirectoryInfo(sourcePath);
var destination = new DirectoryInfo(destinationPath);
CopyFolderContents(sourcePath, destinationPath, "", true, true);
DeleteAll(source, destination);
}
public static void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders)
{
try
{
var exDir = sourceFolder;
var dir = new DirectoryInfo(exDir);
var destDir = new DirectoryInfo(destinationFolder);
SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so))
{
FileInfo srcFile = new FileInfo(sourceFile);
string srcFileName = srcFile.Name;
// Create a destination that matches the source structure
FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, ""));
if (!Directory.Exists(destFile.DirectoryName) && createFolders)
{
Directory.CreateDirectory(destFile.DirectoryName);
}
//Check if src file was modified and modify the destination file
if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists)
{
File.Copy(srcFile.FullName, destFile.FullName, true);
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace);
}
}
private static void DeleteAll(DirectoryInfo source, DirectoryInfo target)
{
if (!source.Exists)
{
target.Delete(true);
return;
}
// Delete each existing file in target directory not existing in the source directory.
foreach (FileInfo fi in target.GetFiles())
{
var sourceFile = Path.Combine(source.FullName, fi.Name);
if (!File.Exists(sourceFile)) //Source file doesn't exist, delete target file
{
fi.Delete();
}
}
// Delete non existing files in each subdirectory using recursion.
foreach (DirectoryInfo diTargetSubDir in target.GetDirectories())
{
DirectoryInfo nextSourceSubDir = new DirectoryInfo(Path.Combine(source.FullName, diTargetSubDir.Name));
DeleteAll(nextSourceSubDir, diTargetSubDir);
}
}
}
它该做的都做了,唯一缺少的是异步复制和sha比较,但至少我有一个解决方案。
我正在学习 C#,我有一个任务:
同步两个目录的内容。
给定两个目录的路径 - dir1 和 dir2,那么 dir2 应该与目录 1 同步:
- 如果一个文件存在于目录 1 而目录 2 中不存在,则应该复制它
-如果一个文件存在于dir1和dir2中,但内容被改变,那么dir1中的文件应该覆盖dir2中的文件
-如果文件存在于 dir2 但不在 dir1 中,则应将其删除
注意:文件可能非常大
-dir1 可以有嵌套文件夹
提示:
-读写文件异步
-哈希文件内容并比较哈希值而不是内容
我有一些关于如何做到这一点的逻辑,但我不知道如何实施it.I 用谷歌搜索整个互联网以找到一个起点,但没有成功。
我从这个开始:
using System.Security.Cryptography;
class Program
{
static void Main(string[] args)
{
string sourcePath = @"C:\Users\artio\Desktop\FASassignment\root\dir1";
string destinationPath = @"C:\Users\artio\Desktop\FASassignment\root\dir2";
string[] dirsInSourcePath = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
string[] dirsInDestinationPath = Directory.GetDirectories(destinationPath, "*", SearchOption.AllDirectories);
var filesInSourcePath = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
var filesInDestinationPath = Directory.GetFiles(destinationPath,"*",SearchOption.AllDirectories);
//Directories in source Path
foreach (string dir in dirsInSourcePath)
{
Console.WriteLine("sourcePath:{0}", dir);
Directory.CreateDirectory(dir);
}
//Directories in destination path
foreach (string dir in dirsInDestinationPath)
{
Console.WriteLine("destinationPath:{0} ", dir);
}
//Files in source path
foreach (var file in filesInSourcePath)
{
Console.WriteLine(Path.GetFileName(file));
}
//Files in destination path
foreach (var file in filesInDestinationPath)
{
Console.WriteLine(Path.GetFileName(file));
}
}
}
据我了解,我应该检查dir1中是否有一些文件夹和文件,如果是,则将它们复制到文件夹2中,依此类推,但是如何做到这一点?我已经焦头烂额两天了,不知道..请帮忙。
编辑:对于第一点和第二点,我找到了解决方案。 :
public static void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders)
{
try
{
/*if (!sourceFolder.EndsWith(@"\")) { sourceFolder += @"\"; }
if (!destinationFolder.EndsWith(@"\")) { destinationFolder += @"\"; }*/
var exDir = sourceFolder;
var dir = new DirectoryInfo(exDir);
SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so))
{
FileInfo srcFile = new FileInfo(sourceFile);
string srcFileName = srcFile.Name;
// Create a destination that matches the source structure
FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, ""));
if (!Directory.Exists(destFile.DirectoryName) && createFolders)
{
Directory.CreateDirectory(destFile.DirectoryName);
}
if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists)
{
File.Copy(srcFile.FullName, destFile.FullName, true);
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace);
}
}
不完美,但works.How这个功能应该改进:添加异步复制,并比较文件的哈希值,不要再次复制相同的文件。怎么做?
所以,经过一段时间的更多研究,我想出了这个解决方案:
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
string sourcePath = @"C:\Users\artio\Desktop\FASassignment\root\dir1";
string destinationPath = @"C:\Users\artio\Desktop\FASassignment\root\dir2";
var source = new DirectoryInfo(sourcePath);
var destination = new DirectoryInfo(destinationPath);
CopyFolderContents(sourcePath, destinationPath, "", true, true);
DeleteAll(source, destination);
}
public static void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders)
{
try
{
var exDir = sourceFolder;
var dir = new DirectoryInfo(exDir);
var destDir = new DirectoryInfo(destinationFolder);
SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so))
{
FileInfo srcFile = new FileInfo(sourceFile);
string srcFileName = srcFile.Name;
// Create a destination that matches the source structure
FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, ""));
if (!Directory.Exists(destFile.DirectoryName) && createFolders)
{
Directory.CreateDirectory(destFile.DirectoryName);
}
//Check if src file was modified and modify the destination file
if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists)
{
File.Copy(srcFile.FullName, destFile.FullName, true);
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace);
}
}
private static void DeleteAll(DirectoryInfo source, DirectoryInfo target)
{
if (!source.Exists)
{
target.Delete(true);
return;
}
// Delete each existing file in target directory not existing in the source directory.
foreach (FileInfo fi in target.GetFiles())
{
var sourceFile = Path.Combine(source.FullName, fi.Name);
if (!File.Exists(sourceFile)) //Source file doesn't exist, delete target file
{
fi.Delete();
}
}
// Delete non existing files in each subdirectory using recursion.
foreach (DirectoryInfo diTargetSubDir in target.GetDirectories())
{
DirectoryInfo nextSourceSubDir = new DirectoryInfo(Path.Combine(source.FullName, diTargetSubDir.Name));
DeleteAll(nextSourceSubDir, diTargetSubDir);
}
}
}
它该做的都做了,唯一缺少的是异步复制和sha比较,但至少我有一个解决方案。