记一次数据库图片引用和服务器文件对比 删除未引用的服务器图片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;
    }
}

实现代码

原文地址:https://www.cnblogs.com/zhyue93/p/winform_task.html

时间: 2024-10-12 02:24:59

记一次数据库图片引用和服务器文件对比 删除未引用的服务器图片1的相关文章

记一次网站前后台分离后公用文件处理过程

在博客园注册好几年了,但是一直也没有养成写博客的习惯,园龄2年3个月,没有博客,没有粉丝,少有关注,还基本每周都要逛几次,按说也算是个奇葩的超级大水B了吧,哈哈. 上半年换了工作,在找工作的各种面试过程中,才发现积累的重要性,很多问题在以往的经历中都或多或少经历过,但是大部分都是浅尝辄止,百度出答案,搬上项目上用,能用就用,不能用改改再用,还不行网上找别的方法用.一直这样,几年下来,问题解决不少,但是想想那些是自己会的,真的把网络断了让我封闭式编程,我还能写出多少东西呢,想想就心惊胆战. 不怕起

记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)

记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的,但是客户反应说CPU占用很高,经常达到80%~90% 我检查了任务管理器,确实是SQLSERVER占的CPU 而服务器的内存是16G内存,只占用了7G+ 客户的环境: Windows2008R2 SQLSERVER2005 SP3 64位 企业版 服务器内存:16G CPU:8核 RDS:阿里云主机

微信图片防盗链“此图片来自微信公众平台 未经允许不可引用”的解决方案

前段时间做微信开发时遇到这个 微信官方防盗链问题 页面显示的微信图片会显示:此图片来自微信公众平台 未经允许不可引用 通过查阅官方的API文档,可以很容易地写出获取用户通过公众号上传的图片地址,也可以通过下载图片的API,下载到本地. 但是, 存在的问题是,下载API调用是有次数限制的,直接通过微信图片地址,本地下载,又比较消耗服务器资源. 网上的各种方法都试过了,比如通过中介服务器地址,这种方法有效,但是同样消耗的是服务器资源,而且用第三方的,总感觉不太靠谱,而且图片的打开速度,还是没有保障的

[WebApi] 捣鼓一个资源管理器--数据库辅助服务器文件访问

<打造一个网站或者其他网络应用的文件管理接口(WebApi)第四章"数据库辅助服务器文件访问"> ======================================================== 作者:qiujuer 博客:blog.csdn.net/qiujuer 网站:www.qiujuer.net 开源库:Genius-Android 转载请注明出处: http://blog.csdn.net/qiujuer/article/details/41721

在服务器上远程链接另一台服务器的数据库的方法how to connet the database from the other host

iwangzheng.com 16:57 [[email protected]]$ mysql -u<username> -p<password> -h10.103.xx.xx Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 571 Server version: 5.0.77 Source distribution Copyright (c) 2000, 20

SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理

原文:SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理 SQL Server 字段类型 decimal(18,6)小数点前是几位? 不可否认,这是一个很低级的问题.... 为什么会问这么低级的问题? 由于这个问题,导致一个数据导入的SP执行失败....以至于困扰了我好几个小时.... 事情是这样的... 公司总部上了一套Oracle的ERP,我们系统中有些数据要从里面取,比如Supplier,Product等. Oracle会导出数据文件,我

关于在服务器上删除文件及删除数据库时的操作问题

1.在服务器上C盘以外的右击delete相当于点击Shift+delete,会将文件彻底删除,无法通过回收站找回:可直接点键盘上的Delete进行删除操作,可通过回收站找回 2.在SQL Server Management Studio上,右击数据库名称Delete会将数据库文件彻底删除,很难恢复 正确操作为: 右击数据库名称,选Tasks,选Take offonline,将数据库离线:如果过一天后无客户投诉,说明该数据库基本处于不使用状态:若有人投诉,该数据库还在使用,赶紧将数据库恢复在线状态

jfreechart 在jsp页面显示所画的图片(resin服务器的servelet配置是关键)(图片只过内存)

用的web服务器是resin服务器,在配置web.xml时需要注意,其实resin服务器的web.xml服务器配置和tomcat服务器的配置很像, 1. 我第一次按照自己的想法,想当然的在resin-pro-3.1.4a\webapps\resin-doc\WEB-INF下的resin-web.xml配置servelet,因为看见这个文件里面的很多语句很像配置servlet的.启动服务器,这样得到的结果当然是后台提示错误, {resin-6} WEB-INF/resin-web.xml:22:

转--图片缓存之内存缓存技术LruCache,软引用

每当碰到一些大图片的时候,我们如果不对图片进行处理就会报OOM异常,这个问题曾经让我觉得很烦恼,后来终于得到了解决,那么现在就让我和大家一起分享一下吧.这篇博文要讲的图片缓存机制,我接触到的有两钟,一种是软引用,另一种是内存缓存技术.先来看下两者的使用方式,再来作比较.除了加载图片时要用到缓存处理,还有一个比较重要的步骤要做,就是要先压缩图片. 1.压缩图片至于要压缩到什么状态就要看自己当时的处境了,压缩图片的时候既要达到一个小的值,又不能让其模糊,更不能拉伸图片.    /**