如何根据名称比较两个不同文件的文件夹?

bal*_*569 4 c# linq

我有两个文件夹A和B ..Inside有多个文件在那里,B里面有多个文件.我必须检查A中的文件,B中的文件用于非相同的文件...我试过这样,它给了整个搜索结果...

var filesnotinboth = from f1 in dir1.GetFiles("*", SearchOption.AllDirectories)
                     from f2 in dir2.GetFiles("*",SearchOption.AllDirectories)
                     where f1.Name != f2.Name
                     select f1.Name;
Run Code Online (Sandbox Code Playgroud)

有什么建议吗?

Jon*_*eet 9

好吧,一方面这种方法效率非常低 - dir2.GetFiles每次开始使用新方法时都会调用f1.然后它将为每个f2当前 不匹配的匹配f1.因此,即使它将在以后 匹配f1,它仍然会输出.想象一下,dir1包含A,B和C,而dir2包含C和D.你最终会这样:

f1    f2    Result of where?
 A     C    True
 A     D    True
 B     C    True
 B     D    True
 C     C    False
 C     D    True
Run Code Online (Sandbox Code Playgroud)

所以结果将是A,A,B,B,C - 你仍然 C(你不想要的) - 只是不像A和B那样频繁.

您想要使用set操作,如下所示:

var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories)
                    .Select(x => x.Name);

var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories)
                    .Select(x => x.Name);

var onlyIn1 = dir1Files.Except(dir2Files);
Run Code Online (Sandbox Code Playgroud)

现在应该工作,更有效率......

编辑:我假设您希望文件在A但不在B中,基于可能的早期版本的问题.(我不确定它是否在前五分钟内被编辑过.显然当前的代码不会返回B中的任何内容而不是A.)

如果您想要对称差异,请使用HashSet<T>.SymmetricExceptWith:

var inExactlyOneDirectory = new HashSet<string>(dir1Files);
inExactlyOneDirectory.SymmetricExceptWith(dir2Files);
Run Code Online (Sandbox Code Playgroud)

(注意,我不喜欢这样SymmetricExceptWith一个事实,即一个改变现有集合的void方法,而不是返回一个新集合或只是一个序列.除了其他任何东西,它意味着变量名称仅适用于第二个语句之后,而不是第一个.)

编辑:如果您需要名称和大小的唯一性,您真的需要一个代表两者的匿名类型.不幸的是,HashSet<T>基于它创建一个很难.所以你需要一个像这样的扩展方法:

public static HashSet<T> ToHashSet<T>(this IEnumerable<T> set)
{
    return new HashSet<T>(set);
}
Run Code Online (Sandbox Code Playgroud)

然后:

var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories)
                    .Select(x => new { x.Name, x.Length });

var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories)
                    .Select(x => new { x.Name, x.Length });

var difference = dir1Files.ToHashSet();
difference.SymmetricExceptWith(dir2Files);
Run Code Online (Sandbox Code Playgroud)