使用 system.IO c# 从 A 合并到 B 目录更新 b 目录
Merge from A to B directory updating b directory using system.IO c#
我想比较两个相同的目录 A 和 B 及其子目录。如果我更改、删除或包含 A 中的目录或文件,我需要反思 B。是否有任何 C# 例程可以执行此操作?我有这个例程,但我无法继续前进。我只想更新我在 A 到 B 中所做的更改,而不是全部。如果我删除 A 中的目录,它不会在 B
中删除
获得每个目录中文件的完整列表后,您可以使用页面 LINQ - Full Outer Join 上记录的 FullOuterJoin 代码。如果您将每个键设为 DirA 和 DirB 下的相对路径加上其他字符,那么您将得到一个很好的比较。这将产生三个数据集——A 中的文件但 B 中不存在的文件、B 中但 A 中不存在的文件以及匹配的文件。然后您可以遍历每个并根据需要执行所需的文件操作。它看起来像这样:
public static IEnumerable<TResult> FullOuterJoin<TA, TB, TKey, TResult>(
this IEnumerable<TA> a,
IEnumerable<TB> b,
Func<TA, TKey> selectKeyA,
Func<TB, TKey> selectKeyB,
Func<TA, TB, TKey, TResult> projection,
TA defaultA = default(TA),
TB defaultB = default(TB),
IEqualityComparer<TKey> cmp = null)
{
cmp = cmp ?? EqualityComparer<TKey>.Default;
var alookup = a.ToLookup(selectKeyA, cmp);
var blookup = b.ToLookup(selectKeyB, cmp);
var keys = new HashSet<TKey>(alookup.Select(p => p.Key), cmp);
keys.UnionWith(blookup.Select(p => p.Key));
var join = from key in keys
from xa in alookup[key].DefaultIfEmpty(defaultA)
from xb in blookup[key].DefaultIfEmpty(defaultB)
select projection(xa, xb, key);
return join;
}
IEnumerable<System.IO.FileInfo> filesA = dirA.GetFiles(".", System.IO.SearchOption.AllDirectories);
IEnumerable<System.IO.FileInfo> filesB = dirB.GetFiles(".", System.IO.SearchOption.AllDirectories);
var files = filesA.FullOuterJoin(
filesB,
f => $"{f.FullName.Replace(dirA.FullName, string.Empty)}",
f => $"{f.FullName.Replace(dirB.FullName, string.Empty)}",
(fa, fb, n) => new {fa, fb, n}
);
var filesOnlyInA = files.Where(p => p.fb == null);
var filesOnlyInB = files.Where(p => p.fa == null);
// Define IsMatch - the filenames already match, but consider other things too
// In this example, I compare the filesizes, but you can define any comparison
Func<FileInfo, FileInfo, bool> IsMatch = (a,b) => a.Length == b.Length;
var matchingFiles = files.Where(p => p.fa != null && p.fb != null && IsMatch(p.fa, p.fb));
var diffFiles = files.Where(p => p.fa != null && p.fb != null && !IsMatch(p.fa, p.fb));
// Iterate and copy/delete as appropriate
我想比较两个相同的目录 A 和 B 及其子目录。如果我更改、删除或包含 A 中的目录或文件,我需要反思 B。是否有任何 C# 例程可以执行此操作?我有这个例程,但我无法继续前进。我只想更新我在 A 到 B 中所做的更改,而不是全部。如果我删除 A 中的目录,它不会在 B
中删除获得每个目录中文件的完整列表后,您可以使用页面 LINQ - Full Outer Join 上记录的 FullOuterJoin 代码。如果您将每个键设为 DirA 和 DirB 下的相对路径加上其他字符,那么您将得到一个很好的比较。这将产生三个数据集——A 中的文件但 B 中不存在的文件、B 中但 A 中不存在的文件以及匹配的文件。然后您可以遍历每个并根据需要执行所需的文件操作。它看起来像这样:
public static IEnumerable<TResult> FullOuterJoin<TA, TB, TKey, TResult>(
this IEnumerable<TA> a,
IEnumerable<TB> b,
Func<TA, TKey> selectKeyA,
Func<TB, TKey> selectKeyB,
Func<TA, TB, TKey, TResult> projection,
TA defaultA = default(TA),
TB defaultB = default(TB),
IEqualityComparer<TKey> cmp = null)
{
cmp = cmp ?? EqualityComparer<TKey>.Default;
var alookup = a.ToLookup(selectKeyA, cmp);
var blookup = b.ToLookup(selectKeyB, cmp);
var keys = new HashSet<TKey>(alookup.Select(p => p.Key), cmp);
keys.UnionWith(blookup.Select(p => p.Key));
var join = from key in keys
from xa in alookup[key].DefaultIfEmpty(defaultA)
from xb in blookup[key].DefaultIfEmpty(defaultB)
select projection(xa, xb, key);
return join;
}
IEnumerable<System.IO.FileInfo> filesA = dirA.GetFiles(".", System.IO.SearchOption.AllDirectories);
IEnumerable<System.IO.FileInfo> filesB = dirB.GetFiles(".", System.IO.SearchOption.AllDirectories);
var files = filesA.FullOuterJoin(
filesB,
f => $"{f.FullName.Replace(dirA.FullName, string.Empty)}",
f => $"{f.FullName.Replace(dirB.FullName, string.Empty)}",
(fa, fb, n) => new {fa, fb, n}
);
var filesOnlyInA = files.Where(p => p.fb == null);
var filesOnlyInB = files.Where(p => p.fa == null);
// Define IsMatch - the filenames already match, but consider other things too
// In this example, I compare the filesizes, but you can define any comparison
Func<FileInfo, FileInfo, bool> IsMatch = (a,b) => a.Length == b.Length;
var matchingFiles = files.Where(p => p.fa != null && p.fb != null && IsMatch(p.fa, p.fb));
var diffFiles = files.Where(p => p.fa != null && p.fb != null && !IsMatch(p.fa, p.fb));
// Iterate and copy/delete as appropriate