如何用C#删除很多文件的文件夹

  各位大神你好,我想用 Directory.Delete(file.FullName, true)删除文件夹,但是在实际应用的时候发现,对容量 小的文件夹进行操作没有问题,但是当对容量非常大的文件夹(几百GB)进行操作的时候程序会卡住,恰好程序就是要用来删除大容量文件夹。
    请问是什么原因导致的呢?我有两个猜想:
    1.是因为线程的问题吗?程序只有主线程,那么是因为删除文件夹要花很多时间,所以软件卡住是为了等待文件夹删除吗?
    2.是否Directory.Delete(file.FullName, true)这命令不适用于删除大文件夹?那么有什么方法可以用来删除大容量的文件夹呢?
#1说得对。
做一件大事情, 首先就是要分解成小任务, 否则容易出问题。

比方说,在数据库里一次删除1亿行记录,就很容易卡住,但循环删除,每次只删除1000行数据就比较容易。

其实,我想说的是,你手动删除大量文件也需要时间的吧。
几百个GB,你想秒级别删完么。。。。

还是想办法把 删除功能 丢子线程去呗,然后主线程做个进度条。

看进度条 慢慢往前动,就不觉得卡住了

这种递归也没用,.

一个文件夹里 有很多文件夹的时候 就算大小非常小..这个时候打开也是非常卡的.. 更别说里面还有那么大文件了..

其实你递归进去删除,意义也不大。
这样删除的时间可能还会再长一点,因为多了递归查找的时间。
其次,你如果用递归,你也是很难用有效的进度条提示的,因为不知道文件总数,你做进度条也是假的进度条。

所以,既然不能减少删除的时间,做进度条也只能做假的进度条,那不如:
新建一个线程,把Directory.Delete(file.FullName, true)放线程里执行,这样至少解决了卡的问题。然后主线程打开一个假的进度提示,慢慢等吧。等线程执行完关闭的时候,再关闭进度提

能不能加个等待线程,删除一定数据后有个等待时间,或者一次删除一定数量数据,加个循环呢

了解各位的意思,其实问题的本质还是出在线程的问题。有个疑问,任务的目标是删除文件夹(实际上是文件夹里面的内容),那么递归进去删除和直接对文件夹进行删除实质上应该是一样的吧?都是对文件进行删除。那么递归进去删除不容易出错,直接删除容易出错?

调用 shell32 的 :SHDeleteFolder
异步,而且有windows标准的进度窗口

用cmd指令删除文件

要让用户有比较好的体验,异步方式比同步好
但是删除文件没有异步方法
个人分析原因:
IO操作本来就是耗时的操作,何况还是超大文件
所以没有特别好的方法来优化替代系统的删除API
应用程序要做的就是把耗时较长的操作放到线程或者Task中去
保证主线程不要被阻塞,
让用户看到在软件在工作,而不是无响应

首先明确一点,你的问题不在于文件大,而是在于文件多。如果是这样的话,C# 删除你使用的是 FILE.DELETE() 还是
NEW FILEINFO().DELETE。这两者效率有差别,楼上说调用CM 使用windows 系统的删除命令可以做,这样确实能快一些,不过系 统命令也是一个一个删除的。如果像STEAM 卸载几十G的游戏那样快,需要涉及操作系统底层的原理,找到磁盘区域开头和结尾设置一下为可复写就可以了。 但是不知道在C#这个层面能否做到。

应该不是文件大,而是文件数量多吧
如果单个文件几百G,删除虽然有点慢,但也不至于有明显卡的感觉

你写的是一个常用的删除过期文件的工具对不对?
如果不是,那还不如直接手动 shift + delete .
是工具,就得考虑各种意外和对你自己和同事而言的便利性。

建议你还是递归来删除。
你反正都几百GB了,文件又多,快一点点或者慢一点点并不是关键。

关键是要知道程序是否正在运行,运行到哪一步了?
程序是否能应对各种复杂情况?比方说某些较新的,特殊扩展名文件要保留等等。
已经删除了的文件,可以用日志记录下来。
对于正在使用,无法删除的文件,还可以异常处理忽略不用删除这个文件。

用子线程删除呀,站在客户角度不影响体验就好。每次删除时开个线程

其实删除文件夹时,其速度取决于子文件夹和文件的个数。  与这个文件夹的大小,关系不大。

如果这 几百G 只有 几十个文件,速度也很快。 如果全是百十来K 的小文件,那一两个小时也不一定能完成。

把这个做为一个后台任务,让它自己去跑比较合适,时不时的查下这个文件夹的大小,反馈给前台用户。

用异步啊,c# 8.0 有个 AsyncStream 

想要删除得快点,就只能把里面的文件进行分线程删除,但是你说的卡住是因为,你的程序是在主线程里面进行删除的,所以会卡住,你把它放到另外一引线程里面
主线程里新增一个子线程去执行,放到子线程执行时,界面还是可以操作的,如果不想被操作,可以把界面的控件设置成disable,子线程代码里,执行完后,再把控件设置回来就行,返回完成的代码也在子线程里写
new Thread(() =>
 {
       删除代码
}).start();

 

几百GB即使在控制台下也是要很久很久的。可以直接后台启动控制台命令

del /s /f /q 文件夹 >nul 即可。

能否先弄一个文件名和后缀一样的小文件,先覆盖大文件,再删除同名小文件呢?
因为删除文件并不是真正在硬盘删除,而是表示硬盘空间可以重新写的
没有几百G的文件来试,请将试验结果分享下。

重点不是文件大小, 而是文件的数量庞大。
大文件删除和小文件没有什么区别,速度基本上是一样的。

首先,要确定删除的不是系统目录、或者档案目录、或者隐藏目录,同时目录中也不含有以上属性文件或者目录。其次,大多数系统对删除操作都是移动到回收站相 似的目录下,而不会是真正的擦除数据。最后,如果是安装的软件,通常可以调用该小蜜蜂论坛发帖机软件的反安装工具,自己做物理删除可能导致系统不稳定;如果擦除的是数据, 通常无法成功,因为系统会自动保护数据文件。

 

根据各位大佬的建议,我思考了下确实是线程的问题,重新修改了程序,把一些更新UI控件的定时器和删除动作放到了线程里,删除方法优化了下,用迭代的方法 先遍历出所有符合条件的文件夹目录并加入list中,然后按照list的列表按顺序删除(对删除时间的快慢没有要求,只维持磁盘阈值就可以了,所以没有用 几个线程一起删除),并且按照list创建了个进度条。昨晚挂在服务器上测试了下,效果不错。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值