zoukankan      html  css  js  c++  java
  • 记一次数据库图片引用和服务器文件对比 删除未引用的服务器图片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;
        }
    }
    实现代码
  • 相关阅读:
    A/B test模块使用以及配置
    Linux下的tar压缩解压缩命令详解
    php mysql转义特殊字符的函数(转)
    cas server + cas client 单点登录 原理介绍
    php二维码的生产以及下载
    shiro 获取已经登录的用户
    Sql 根据多条件查询重复的数据 MySQL删除重复数据
    js base64 转PDF并下载,js baser64转图片并下载
    当同时安装Python2和Python3后,如何兼容并切换使用详解(比如pip使用)
    我的博客初始“话”
  • 原文地址:https://www.cnblogs.com/zhyue93/p/winform_task.html
Copyright © 2011-2022 走看看