所以我有一个带有子文件夹和大约500k图像的主目录。我知道我的数据库中不存在很多theese图像,我想知道哪些图像可以删除它们。
这是我到目前为止的代码:
var listOfAdPictureNames = ImageDB.GetAllAdPictureNames();
var listWithFilesFromImageFolder = ImageDirSearch(adPicturesPath);
var result = listWithFilesFromImageFolder.Where(p => !listOfAdPictureNames.Any(q => p.FileName == q));
var differenceList = result.ToList();
listOfAdPictureNames的类型为List<string>
这是我从ImageDirSearch中退出的模型:
public class CheckNotUsedAdImagesModel
{
public List<ImageDirModel> ListWithUnusedAdImages { get; set; }
}
public class ImageDirModel
{
public string FileName { get; set; }
public string Path { get; set; }
}
这是从我的文件夹中获取所有图像的递归方法。
private List<ImageDirModel> ImageDirSearch(string path)
{
string adPicturesPath = ConfigurationManager.AppSettings["AdPicturesPath"];
List<ImageDirModel> files = new List<ImageDirModel>();
try
{
foreach (string f in Directory.GetFiles(path))
{
var model = new ImageDirModel();
model.Path = f.ToLower();
model.FileName = Path.GetFileName(f.ToLower());
files.Add(model);
}
foreach (string d in Directory.GetDirectories(path))
{
files.AddRange(ImageDirSearch(d));
}
}
catch (System.Exception excpt)
{
throw new Exception(excpt.Message);
}
return files;
}
我遇到的问题是这一行:
var result = listWithFilesFromImageFolder.Where(p => !listOfAdPictureNames.Any(q => p.FileName == q));
需要一个多小时才能完成。我想知道是否有更好的方法来检查我的images文件夹中是否存在我的数据库中不存在的图像。
以下是从我的数据库层获取所有图像名称的方法:
public static List<string> GetAllAdPictureNames()
{
List<string> ListWithAllAdFileNames = new List<string>();
using (var db = new DatabaseLayer.DBEntities())
{
ListWithAllAdFileNames = db.ad_pictures.Select(b => b.filename.ToLower()).ToList();
}
if (ListWithAllAdFileNames.Count < 1)
return new List<string>();
return ListWithAllAdFileNames;
}
答案 0 :(得分:1)
或许Except正是您所寻找的。像这样:
var filesInFolderNotInDb = listWithFilesFromImageFolder.Select(p => p.FileName).Except(listOfAdPictureNames).ToList();
应该为您提供文件夹中但不在数据库中的文件。
答案 1 :(得分:0)
正如我在评论中所说,您似乎已经重新创建了FileInfo
课程,您不需要这样做,因此您的ImageDirSearch
可以成为以下
private IEnumerable<string> ImageDirSearch(string path)
{
return Directory.EnumerateFiles(path, "*.jpg", SearchOption.TopDirectoryOnly);
}
通过返回只需要文件名的整个文件信息似乎没有多少收获,而且这只能找到jpgs,但这可以改变..
ToLower
调用非常昂贵并且有点无意义,当您计划再次查询时列出的内容也是如此,以便您可以摆脱它并再次返回IEnumerable
(这是在GetAllAdPictureNames
方法中)
然后你的比较可以使用equals并忽略大小写。
!listOfAdPictureNames.Any(q => p.Equals(q, StringComparison.InvariantCultureIgnoreCase));
可能有帮助的另一件事就是从文件名列表中删除项目,这样可以在每次删除文件时更快地搜索列表,因为迭代次数较少。
答案 2 :(得分:0)
不是在每个列表上重复搜索,而是对第二个列表“listOfAdPictureNames”(使用n * log(n)排序中的任何一个)进行排序。然后通过二分搜索检查存在将是所有其他技术中最有效的,包括当前的顺序是指数的。