编程与数学 03-007 《看潮资源管理器》项目开发 18 文件夹操作(2-2)
编程与数学 03-007 《看潮资源管理器》项目开发 18 文件夹操作(2-2)
- 三、文件夹查重
- (一)需求描述
- (二)前端代码
- (三)后台代码
- 四、文件夹简单查重
- (一)需求描述
- (二)前端代码
- (三)后台代码
- 全文总结
摘要: 本文实现《看潮资源管理器》文件夹复制、删除、查重三大功能:复制前校验存在性与用户确认,递归拷贝并跳过已存在目标;删除同步移除物理目录及数据库fm_DirectoryInfo、fm_FileInfo记录,采用倒序遍历防索引错乱;查重提供名称+大小+文件数精准模式与仅名称快速模式,存储过程游标标记后建重复项,返回重复计数并刷新界面。
关键词: 文件夹复制、递归拷贝、文件夹删除、数据库级联删除、文件夹查重、名称大小文件数匹配、存储过程游标、IsSelect标记、WinForms、NET8
三、文件夹查重
(一)需求描述
文件夹查重,查询当前所有者的所有存储器中,哪些文件夹是重复的,重复的文件夹将被选定。
(二)前端代码
case "文件夹查重":string sqlcc = "EXEC [rmDirDupCheck] @Owner";string result = _dbHelper.ExecuteSql(sqlcc, new SqlParameter("@Owner", cuOwner));MessageBox.Show("按照名称、大小和文件数进行的文件夹查重已经完成!\r\n" + $"当前所有者有{result}个重复的文件夹。\r\n" +"文件夹数据将重新载入!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);loadDt(false, true, false, false);break;
(三)后台代码
USE [RsManagerDb]
GO
/****** Object: StoredProcedure [dbo].[rmDirDupCheck] Script Date: 2025-09-26 11:25:57 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO-- =============================================
-- Author: 岳国军
-- Create date: 2025-06-22
-- Description: 文件夹查重
-- =============================================
ALTER PROCEDURE [dbo].[rmDirDupCheck](@Owner NVARCHAR(50))
AS
BEGINDECLARE @Id int ,@LengthMb decimal(16,2),@Name NVARCHAR(500),@FilesCount int;UPDATE fm_DirectoryInfo SET IsSelect=0 WHERE (Owner=@Owner);DECLARE DIR_cursor CURSOR LOCAL FORSELECT Id,Name,LengthMb,FilesCount FROM fm_DirectoryInfo WHERE Owner =@Owner ORDER BY Id ;OPEN DIR_cursor;FETCH FROM DIR_cursor INTO @Id,@Name,@LengthMb,@FilesCount;WHILE @@FETCH_STATUS=0BEGINIF EXISTS(SELECT ID,NAME FROM fm_DirectoryInfo WHERE (Owner=@Owner) AND (Id<@ID) AND (NAME=@NAME AND LengthMb=@LengthMb AND FilesCount=@FilesCount))UPDATE fm_DirectoryInfo SET IsSelect=1 WHERE Id=@Id ; FETCH NEXT FROM DIR_cursorINTO @Id,@Name,@LengthMb,@FilesCount;ENDCLOSE DIR_cursor;DEALLOCATE DIR_cursor ;SELECT count(*) FROM fm_DirectoryInfo where isselect=1 AND Owner=@Owner;END--SELECT * FROM fm_DirectoryInfo ;--SELECT * FROM fm_FileInfo
存储过程功能总结:
- 输入参数:
@Owner- 文件夹所有者 - 主要功能:检查指定用户下是否存在重复文件夹
- 重复条件:文件夹名称、大小(LengthMb)、文件数量(FilesCount)完全相同
- 处理逻辑:
- 先重置所有文件夹的标记状态
- 使用游标遍历每个文件夹
- 检查是否存在ID更小但其他属性相同的文件夹
- 标记重复的文件夹(保留最先创建的,标记后创建的)
- 输出结果:返回重复文件夹的数量
注意事项:
- 该存储过程使用游标逐行处理,对于大量数据可能存在性能问题
- 重复判断基于名称、大小和文件数量的精确匹配
- 只标记后创建的重复项(ID更大的记录)
四、文件夹简单查重
(一)需求描述
文件夹简单查重,只按文件夹名称查重。范围是当前所有者的所有存储器中。
(二)前端代码
case "文件夹简单查重":string sqlccname = "EXEC [rmDirDupName] @Owner";string resultname = _dbHelper.ExecuteSql(sqlccname, new SqlParameter("@Owner", cuOwner));MessageBox.Show("按照文件夹名称进行的文件夹简单查重已经完成!\r\n" + $"当前所有者有{resultname}个重复的文件夹。\r\n" +"文件夹数据将重新载入!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);loadDt(false, true, false, false);break;
(三)后台代码
USE [RsManagerDb] -- 指定使用的数据库
GO/****** Object: StoredProcedure [dbo].[rmDirDupName] Script Date: 2025-09-26 11:33:29 ******/
SET ANSI_NULLS ON -- 设置ANSI_NULLS为ON,确保与NULL值的比较符合ANSI SQL标准
GO
SET QUOTED_IDENTIFIER ON -- 设置QUOTED_IDENTIFIER为ON,允许使用双引号来分隔标识符
GO-- =============================================
-- Author: 岳国军
-- Create date: 2025-06-22
-- Description: 文件夹查重 - 基于文件夹名称检查重复项
-- 功能:检查指定用户下是否存在同名文件夹,标记后创建的重复文件夹
-- =============================================
ALTER PROCEDURE [dbo].[rmDirDupName](@Owner NVARCHAR(50)) -- 输入参数:文件夹所有者/用户标识
AS
BEGIN-- 声明变量用于存储游标遍历时的当前行数据DECLARE @Id int, -- 当前文件夹的唯一标识ID@Name NVARCHAR(500); -- 当前文件夹的名称-- 初始化操作:将指定用户的所有文件夹的IsSelect标记重置为0(未选中状态)-- 为后续的重复检查做准备,确保所有记录初始状态一致UPDATE fm_DirectoryInfo SET IsSelect = 0 WHERE (Owner = @Owner); -- 只更新指定所有者的记录-- 声明一个本地游标,用于逐行遍历指定用户的所有文件夹记录-- LOCAL表示游标仅在当前存储过程中有效DECLARE DIR_cursor CURSOR LOCAL FORSELECT Id, Name -- 只选择ID和名称字段,因为只需基于名称查重FROM fm_DirectoryInfo WHERE Owner = @Owner -- 限定只查询指定所有者的文件夹ORDER BY Id; -- 按ID升序排列,确保先处理先创建的文件夹-- 打开游标,准备开始遍历数据OPEN DIR_cursor;-- 获取游标中的第一行数据,将值存储到声明的变量中FETCH FROM DIR_cursor INTO @Id, @Name;-- 开始循环遍历游标中的所有记录-- @@FETCH_STATUS = 0 表示成功获取到一行数据WHILE @@FETCH_STATUS = 0BEGIN-- 检查是否存在重复项:同一所有者、ID更小(创建时间更早)、名称相同的文件夹IF EXISTS(SELECT ID, NAME FROM fm_DirectoryInfo WHERE (Owner = @Owner) -- 属于同一所有者AND (Id < @ID) -- ID比当前文件夹小(创建时间更早)AND (NAME = @NAME) -- 文件夹名称完全相同)-- 如果找到重复项(存在同名且更早创建的文件夹),将当前文件夹标记为重复UPDATE fm_DirectoryInfo SET IsSelect = 1 -- 设置标记为1,表示这是重复项WHERE Id = @Id; -- 只更新当前文件夹的记录-- 获取游标中的下一行数据,继续循环处理FETCH NEXT FROM DIR_cursorINTO @Id, @Name;END-- 循环结束后,关闭游标释放资源CLOSE DIR_cursor;-- 释放游标占用的系统资源DEALLOCATE DIR_cursor;-- 返回查询结果:统计指定用户下被标记为重复的文件夹数量SELECT count(*) FROM fm_DirectoryInfo WHERE isselect = 1 AND Owner = @Owner;END-- 以下是注释掉的调试语句,在需要调试时可以取消注释来查看完整数据
-- SELECT * FROM fm_DirectoryInfo ; -- 查看所有文件夹信息
-- SELECT * FROM fm_FileInfo -- 查看所有文件信息
存储过程功能详细说明:
- 主要目的:检测指定用户下是否存在同名文件夹,并标记后创建的重复项
- 查重逻辑:
- 仅基于文件夹名称进行重复判断
- 保留最先创建的文件夹(ID最小的),标记后创建的重复文件夹
- 只检查同一用户下的文件夹重复情况
- 处理流程:
- 初始化所有文件夹的标记状态
- 使用游标按创建顺序(ID顺序)遍历每个文件夹
- 对每个文件夹,检查是否存在同名且更早创建的文件夹
- 如果存在,将当前文件夹标记为重复
- 返回重复文件夹的总数
- 输出结果:返回被标记为重复的文件夹数量
- 适用场景:需要快速检查文件夹名称重复的情况,相比完整属性查重性能更高
全文总结
本章围绕“文件夹操作”给出完整、安全、可反馈的解决方案。复制功能先统计IsSelect行并二次确认,再弹出FolderBrowserDialog选定目标,逐行合成源路径后调用CopyDirectory递归拷贝子文件与目录,目标已存在则自动跳过;UI实时提示成功与失败项。删除功能同样先确认,再用倒序遍历gridDir行,物理调用Directory.Delete(recursive:true)后,立即以参数化SQL删除fm_DirectoryInfo内该Id及同级子目录,并清理fm_FileInfo中的关联文件记录,最后移除DataGridView行并重新载入数据,避免索引错位与幽灵条目。查重分为“精准”与“简单”两模式:前者执行rmDirDupCheck,按名称、大小(LengthMb)、文件数三字段判重;后者执行rmDirDupName,仅按名称判重;两存储过程均用游标按Id升序扫描,保留最早创建项,把后建重复项IsSelect置1并返回重复数量,前端接收结果后刷新网格,用户可一键查看或进一步处理重复文件夹。整套代码兼顾事务安全、异常提示与操作可撤销性,为大容量媒体库维护提供可靠工具。
