获取数据表中不存在的所有文件

Posted

技术标签:

【中文标题】获取数据表中不存在的所有文件【英文标题】:Get all files not present int a datatable 【发布时间】:2016-06-08 20:49:48 【问题描述】:

我有一个带有文件名列表的 mysql 表。 仅当表中不存在名称时,我才想获取目录中所有文件的列表。

我可以将数据库文件的列表放在数据表中,然后写如下内容:

 string[] files = Directory.GetFiles(directory);
 foreach (Datarow row in dataTable.Rows)
   for (int i=0; i<files.Length; i++)
      if (row[0].equals(files[i]) 
          files[i].delete();
          break;
       

上面的代码只是一个伪示例。我不能通过指定过滤器直接使用 Directory.GetFiles(directory) 以不编写所有迭代吗?

【问题讨论】:

不,没有办法使用它,但是您可以使用 if(files.IndexOf(row[0].ToString()) 例如,如果您想获取以.txt 结尾的文件列表,您可以执行以下var files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).Where(name =&gt; name.EndsWith(".txt")).ToList();,如果您可以这样做.. 为什么不能替换@987654324 @ 方法与.Contains 并获取包含特定字符串值的所有文件..? 【参考方案1】:

请在下面找到代码sn-p

决定分步进行 - 拥有更多可维护的代码

void Main()

    // given a list of files from db
    DataTable dataTable = new DataTable("x");  
    dataTable.Columns.Add("file", typeof(string));  
    dataTable.Rows.Add("HaxLogs.txt");dataTable.Rows.Add("swapfile.sys");dataTable.Rows.Add("four.txt");
    var directory = "c:\\";
    var directoryFilesWithPaths = Directory.GetFiles(directory)
            .Select( x=> new FileEntry  Path = x, FileName = Path.GetFileName(x));

            var directoryFiles = directoryFilesWithPaths.Select(x => x.FileName).ToList();
            var filesList = (from DataRow dr in dataTable.Rows
                            select dr[0].ToString()).ToList();

            var filesToProcess = directoryFiles.Except(filesList);
        foreach (var file in filesToProcess)
        
            // process file here

            Console.WriteLine(file);
        

【讨论】:

嗨,有一个我没有说的问题:在数据表中有没有路径的文件名,但是有 String[] files = Directory.GetFiles(tDirectory.Text, ".", System.IO.SearchOption.AllDirectories); 我也得到了路径。 我试过 var filesToProcess = files.Select(Path.GetFileName).Except(filesList); 但不起作用。 有一个补丁 :-) 谢谢,但是这样你不会丢失我在你最后一次 foreach 中需要的路径 + 文件名吗?我们不能在您的第一个示例的 var filesToProcess 中进行 Select,作为我的第二条评论吗? 请寻找我的解决方案 :)【参考方案2】:

一个 linq 解决方案是:

Directory.GetFiles(directory)
         .Where(x => !dataTable.AsEnumerable()
                .Select(row => row[0].ToString()) 
                .Contains(x))

【讨论】:

我试过你的解决方案,但结果是目录中所有文件的列表,没有过滤。 一种可能的解释是该表包含的数据与 Directory.GetFiles 的结果完全不同。例如,表可能有文件名,但 GetFiles 返回完整路径。 是的,正如你所说。我需要选择所有以数据库行结尾的文件。 如果“以谁结尾”是指文件名和扩展名,那么你只需要更改这部分.Contains(Path.GetFileName(x))) 谢谢,它可以工作,但是professor79的解决方案更快。【参考方案3】:

这是我的解决方案:

 ArrayList files = new ArrayList();
 files.AddRange(Directory.GetFiles(directory, "*.*", SearchOption.AllDirectories));
        foreach (DataRow row in tableFiles.Rows)
        
            for (int i = 0; i < files.Count; i++)
                if (files[i].ToString().EndsWith(row[0].ToString()))
                
                    files.RemoveAt(i);
                    break;
                
        

我还尝试使用 Path.GetFileName(files[i].ToString() 以使用 Equals 而不是 EndsWith,但是对于 8500 个文件,此解决方案需要 2 秒,GetFileName 需要 10 秒。

【讨论】:

看起来不错 - 但循环可能很昂贵 但是这样我还是有完整的文件名,你认为我们可以改进这个解决方案吗? 这是真的 - 这个关于文件数量的信息应该是你的问题。

以上是关于获取数据表中不存在的所有文件的主要内容,如果未能解决你的问题,请参考以下文章

获取另一个表中不存在的所有项目

mysql获取条件中描述的所有记录,即使表中不存在

即使数据库中不存在也显示记录

即使数据库中不存在,也要显示记录

SQLite查询选择另一个表中不存在的所有记录

Sql Server中不存在原理dbo