记一次数据库图片引用和服务器文件对比 删除未引用的服务器图片1
Posted zhyue93
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次数据库图片引用和服务器文件对比 删除未引用的服务器图片1相关的知识,希望对你有一定的参考价值。
需求:
服务器上图片达到上百G,但是数据库查询才30多万条记录有被引用,多数是无效的图片但是未物理删除
分析:
要能手动选择要检查的服务器文件目录,支持多个以英文逗号隔开
记录下未被数据库引用的目录或图片地址(要能输入名称的txt文件,要能选择该文件的存放目录)
假如程序出错崩溃,要记录下当前查询到哪一个目录和文件的地址(以便于下一次重启不用重新开始)
实现:
/// <summary> /// 要保存的文件路径 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSavePath_Click(object sender, EventArgs e) { FolderBrowserDialog dialog = new FolderBrowserDialog(); if (dialog.ShowDialog() == DialogResult.OK) { if (string.IsNullOrEmpty(dialog.SelectedPath)) { MessageBox.Show("路径不能为空"); return; } lblTxtSavePath.Text = dialog.SelectedPath; } } /// <summary> /// 开始执行比对 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnDo_Click(object sender, EventArgs e) { //要保存的txt文件名称 string txtFileName = txtSaveName.Text.Trim(); if (txtFileName.Length <= 0) { MessageBox.Show("txt文件名称不能为空"); return; } if (!txtFileName.EndsWith(".txt")) txtFileName = lblTxtSavePath.Text + "\\\\" + txtFileName + ".txt"; //当前查询截止的目录 string currPath = lblTxtSavePath.Text + "\\\\" + "currPath.txt"; //要搜索的文件夹路径 string searchPaths = txtSearchPath.Text.Trim(); if (searchPaths.Length <= 0) { MessageBox.Show("要搜索的文件夹路径不能为空"); return; } string[] searchPathArr = searchPaths.Split(\',\'); //禁用当前按钮 防止重复执行 DisableFormControls(); Task.Factory.StartNew(() => { //最终服务器上图片不在数据库中的路径 List<string> imageTargetUrls = new List<string>(); //从数据库中读取 [Type=\'房源\' OR Type=\'楼盘\'] 的图片地址 DataTable dtUrl = GetData(); if (dtUrl != null && dtUrl.Rows.Count > 0) { //从要搜索的文件夹路径中找出所有的图片及其路径 key=路径 value=值 //Dictionary<string, string> imageDic = new Dictionary<string, string>(); if (searchPathArr != null && searchPathArr.Length > 0) { foreach (var path in searchPathArr) { if (Directory.Exists(path)) { getFile(path, ".jpg.JPEG.PNG.bmp.png.GIF", dtUrl, txtFileName, currPath); } } } } Invoke(new Action(() => { EnableFormControls(); MessageBox.Show(this, "执行完成"); })); }); } /// <summary> /// 禁用当前窗口的可操作控件 /// </summary> private void DisableFormControls() { btnDo.Enabled = false; btnSavePath.Enabled = false; txtSaveName.Enabled = false; txtSearchPath.Enabled = false; } /// <summary> /// 启用当前窗口的可操作控件 /// </summary> private void EnableFormControls() { btnDo.Enabled = true; btnSavePath.Enabled = true; txtSaveName.Enabled = true; txtSearchPath.Enabled = true; } /// <summary> /// 从数据库获取数据 /// </summary> private static DataTable GetData() { DataTable dt = null; string str_sql_conn = ConfigurationManager.AppSettings["sql_connect_str"]; using (SqlHelper conn = new SqlHelper(str_sql_conn)) { string sql_text = @"SELECT URL FROM dbo.T_Attachment WHERE Type=\'房源\' OR Type=\'楼盘\'"; dt = conn.ExecuteDs(sql_text, CommandType.Text, null).Tables[0]; } return dt; } /// <summary> /// 获得目录下所有文件或指定文件类型文件(包含所有子文件夹) /// 记录当前查询截止的目录(防止程序崩溃 下次从这个地方重启) /// 查询当前目录是否在数据库中被引用 /// 记录当前查询截止的文件地址(防止程序崩溃 下次从这个地方重启) /// 查询当前目录下的图片是否在数据库中被引用 /// 记录未被数据库引用的图片的路径 /// </summary> /// <param name="path"></param> /// <param name="extName"></param> /// <param name="dtUrl"></param> /// <param name="txtFileName"></param> /// <param name="currPath"></param> public static void getFile(string path, string extName, DataTable dtUrl, string txtFileName, string currPath) { try { //记录当前查到了哪个文件夹 File.AppendAllLines(currPath, new string[] { path }); //判断当前路径是否在数据库中有引用 如果不存在 不需要判断当前目录下的子目录及子文件 string dictionaryLastName = path.Split(new string[] { "\\\\upload" }, StringSplitOptions.None)[1].Replace("\\\\", "/"); if (!dtUrl.AsEnumerable().Any(s => s.Field<string>("URL").ToLower().Contains(dictionaryLastName.ToLower()))) { File.AppendAllLines(txtFileName, new string[] { path }); return; } string[] dir = Directory.GetDirectories(path); //文件夹列表 DirectoryInfo fdir = new DirectoryInfo(path); FileInfo[] file = fdir.GetFiles(); if (file.Length != 0 || dir.Length != 0) //当前目录文件或文件夹不为空 { foreach (FileInfo f in file) //显示当前目录所有文件 { //判断是否为图片 if (extName.ToLower().IndexOf(f.Extension.ToLower()) >= 0) { //记录当前查到了哪个图片文件 File.AppendAllLines(currPath, new string[] { f.FullName }); //判断当前文件是否在数据库中被引用 if (!dtUrl.AsEnumerable().Any(s => s.Field<string>("URL").ToLower().Contains(f.Name.ToLower()))) {//数据库中不包含服务器上文件夹中的图片 //记录下当前图片的路径 File.AppendAllLines(txtFileName, new string[] { f.FullName }); } } } foreach (string d in dir) { getFile(d, extName, dtUrl, txtFileName,currPath);//递归 } } } catch (Exception ex) { throw ex; } }
以上是关于记一次数据库图片引用和服务器文件对比 删除未引用的服务器图片1的主要内容,如果未能解决你的问题,请参考以下文章