Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 比较两个目录时出现问题_C# - Fatal编程技术网

C# 比较两个目录时出现问题

C# 比较两个目录时出现问题,c#,C#,我试图比较两个目录,看看目录1中哪些文件不在目录2中。我有以下代码: System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA); System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB); IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.PRN"); IEnumerabl

我试图比较两个目录,看看目录1中哪些文件不在目录2中。我有以下代码:

System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA);
System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB);

IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.PRN");
IEnumerable<System.IO.FileInfo> list2 = dir2.GetFiles("*.PRN");

IEnumerable<System.IO.FileInfo> list3 = list1.Except(list2);

Console.WriteLine("The following files are in list1 but not list2:");

foreach (var v in list3)
{
    Console.WriteLine(v);
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
System.IO.DirectoryInfo dir1=新的System.IO.DirectoryInfo(路径A);
System.IO.DirectoryInfo dir2=新的System.IO.DirectoryInfo(路径B);
IEnumerable list1=dir1.GetFiles(“*.PRN”);
IEnumerable list2=dir2.GetFiles(“*.PRN”);
IEnumerable list3=list1.Except(list2);
WriteLine(“以下文件在列表1中,但不在列表2中:”);
foreach(列表3中的var v)
{
控制台写入线(v);
}
Console.WriteLine(“按任意键继续…”);
Console.ReadKey();
运行时,它会清楚地列出目录1中的所有文件,但其中许多文件已经在目录2中。我可以通过查看Windows资源管理器和文件名来了解这一点。我错过了什么

编辑:

我相信问题出在文件比较部分。我试图让它忽略文件扩展名的情况。我试过这个:

    class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{
    public FileCompare() { }

    public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
    {
        //return (f1.Name.ToUpper == f2.Name.ToUpper &&
        //        f1.Length == f2.Length);

        return (string.Equals(f1.Name, f2.Name, StringComparison.OrdinalIgnoreCase) && f1.Length == f2.Length);
    }

    public int GetHashCode(System.IO.FileInfo fi)
    {
        string s = String.Format("{0}{1}", fi.Name, fi.Length);
        return s.GetHashCode();
    }
}
类文件比较:System.Collections.Generic.IEqualityComparer
{
公共文件比较(){}
public bool等于(System.IO.FileInfo f1、System.IO.FileInfo f2)
{
//返回(f1.Name.ToUpper==f2.Name.ToUpper&&
//f1.长度==f2.长度);
返回(string.Equals(f1.Name,f2.Name,StringComparison.OrdinalIgnoreCase)和&f1.Length==f2.Length);
}
public int GetHashCode(System.IO.FileInfo-fi)
{
string s=string.Format(“{0}{1}”,fi.Name,fi.Length);
返回s.GetHashCode();
}
}

但这仍然不起作用。你可以看到,我注释掉了另一个尝试,只是在比较中把所有内容都置为大写,但它不会这样做

您需要使用重载版本的
Except()
并将
IEqualityComparer
的自定义实现传递给它,该实现准确地指示了定义两个
FileInfo
对象精确匹配的标准

请参见此处的示例,并根据自己的需要进行修改:

上有一个示例向您展示了如何做到这一点

创建您的
IEqualityComparer
实现

class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{
    public FileCompare() { }

    public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
    {
        return (f1.Name == f2.Name &&
                f1.Length == f2.Length);
    }

    public int GetHashCode(System.IO.FileInfo fi)
    {
        string s = String.Format("{0}{1}", fi.Name, fi.Length);
        return s.GetHashCode();
    }
}
你可以用LINQ

        var list3 = from c in list1
                    where !(from o in list2
                            select o.Name)
                           .Contains(c.Name)
                    select c;
不同情况下也可能存在问题

你可以试试

.Equals(c.Name, StringComparison.OrdinalIgnoreCase)
而不是

.Contains(c.Name)

或者在比较之前将所有内容转换为小写。

由于您只对名称感兴趣,请使用
将您的序列投影到名称序列中。选择
LINQ的扩展方法:

IEnumerable<string> list1 = dir1.GetFiles("*.PRN").Select(fi => fi.Name);
IEnumerable<string> list2 = dir2.GetFiles("*.PRN").Select(fi => fi.Name);
IEnumerable<string> list3 = list1.Except(list2);
IEnumerable list1=dir1.GetFiles(“*.PRN”)。选择(fi=>fi.Name);
IEnumerable list2=dir2.GetFiles(“*.PRN”)。选择(fi=>fi.Name);
IEnumerable list3=list1.Except(list2);
(您可以使用
var
,隐式键入。)


这是因为
string
的默认相等比较程序执行顺序和区分大小写的比较(不只是像
FileInfo
类那样的引用相等比较)。

FileInfo还保存日期和时间信息。您不应该只比较文件名吗?您确定文件名中没有细微的差异吗?我认为
System.IO.FileInfo
Equals()
方法不能满足您的需要。为什么不定义文件“已经在目录2中”的含义?你是说相同的文件名吗?完全相同的字节?是的,我正在寻找完全相同文件名的文件。@roliu你说得对。
FileInfo
类或其任何基类都不会覆盖
Equals
方法,因此这使用了从这些
virtual
方法的
System.Object
实现继承的引用等式。这是我最初尝试的方法,但也不起作用。所以我尝试了更简单的方法。两者仍然返回存在于两个目录中的文件,我只想查看目录1中的文件。@RobertWiglesworth此解决方案将很好,您只需在比较器中进行不区分大小写的比较
String.Compare(f1.Name,f2.Name,StringComparison.OrdinalIgnoreCase)==0
@LeeHiles如果您需要,请使用
String.Equals(f1.Name,f2.Name,StringComparison.OrdinalIgnoreCase)
。嘿,伙计们,我已经尝试了您提到的两种方法。当前,我的文件比较器如下所示:return(string.Equals(f1.Name,f2.Name,StringComparison.OrdinalIgnoreCase)和&f1.Length==f2.Length);它仍然不起作用。@RobertWiglesworth-尝试删除
f1.Length==f2.Length
检查是否有效。这意味着文件不一样(大小不同),但名称不同。这仍然显示了列表1中的所有文件,即使它们存在于列表2中。这很奇怪。。。你确定名字完全一样吗?(同样的情况,不是额外的空间)好的,这里有一些奇怪的。。。我试着用Intersect来代替,看看它是否列出了任何相同的东西。我得到了一个值。这是一个文件,我手动从dir1复制到dir2只是为了确保我有正确的文件夹权限。我检查了它们的属性,dir1将它们显示为file type.prn,dir2将它们显示为file type.prn。这是一个系统首选项还是什么?好的,这似乎归结为一个目录的扩展名是小写的,而另一个目录的扩展名是大写的。我在通过Windows资源管理器查看时没有意识到这一点,因为它不显示文件扩展名。有没有办法让它忽略扩展的情况?甚至完全忽略扩展?@Robert I更新了回复。您还可以查看System.IO.Path类。
IEnumerable<string> list1 = dir1.GetFiles("*.PRN").Select(fi => fi.Name);
IEnumerable<string> list2 = dir2.GetFiles("*.PRN").Select(fi => fi.Name);
IEnumerable<string> list3 = list1.Except(list2);