磁盘可用空间平衡

      我经常收集各种感兴趣的文件,我想,你可能也一样,收集自己喜欢的音乐、电影、软件等。久而久之磁盘接近满了,或者一些分区快满了。于是出现一些问题待我们去解决。问题一,少于200M时winXP系统会报告空间低,当然你可以关掉这个警告的功能,但磁盘空间低已是事实,可能会造成一些软件工作受影响,例如迅雷。如果是系统盘----准确地说是虚拟内在页面文件所在的分区----那就更危险了,造成系统虚拟内存不足。问题二,你想从别处Copy来一个文件,此文件的大小尚在磁盘总体可用空间范围之内,却发现每个分区的可用空间都太小,放不下这个文件。或许还有问题三,等着你去发现。解决这些问题的方法除了加磁盘或删除文件等做法,而我更多的时候会选择移动文件,以后有时间再去选择哪些文件应该清掉。

      移哪些文件往往也是一个头疼的问题,有些文件是不能移的,否则会工作不正常,比如Windows文件夹里的,我们能移的是一些类似doc文档、音乐、电影这些文件。剩下的就是移哪个或哪几个,本质上讲就是要移动的Size之和是多大,如果你想磁盘各分区剩余空间尽可能接近的话,这个计算是比较麻烦的。然后就是移动文件,可能还有再计算,再移动,直至自我感觉差不多,整个过程会花掉你不少时间和精力。如果,如果有一款软件自动帮我收集信息、自动计算、自动移动,那不是省了不少事?这些事理论上是可以由工具软件来替我做的,而偏偏我找了两年,用尽我能想到的关键字,就是没找到类似的软件,没办法,只好自己做。

      我们知道,文件的移动是一个很慢的过程,于是我们希望尽量少地移动文件,还要防止一个文件移过去了,又移回来----我把这个称为“回流现象”,简称“回流”----,如果有回流,说明计算过程是有缺陷的,而且有可能产生死循环,于是设计一套科学有效的算法至关重要。于是经过思考后有了这张图:

假设有4个分区,每根柱代表了该分区已存文件的多少,每个分区都满的情况下,所有柱的上端是平齐的,即是说分区总大小的差异体现在下端。去掉了分总大小的差异后,我们就可以只考虑可用空间了,即柱的上方。

      由上图可看出,从左边数,第1个分区可用空间最少(装的最满),第3个分区可用空间最多。于是可以确定从第1分区移一些文件到第3分区。接下来是移多少的问题。首先算出4个分区的平均可用空间,即图中的average线,只要移后第1分区不低于average,第3分区不高于average,即可保证不会产生回流。于是算出它们分别与average的距离:

第1分区:A = highest - average

第2分区:B = average - lowest

而要移动的文件大小就是A和B中的最小值,即 C = Math.Min(A, B),对应图上的一对大箭头。

当然了,如果能找到一些文件的大小之和刚好是C是最好的,实际情况往往是差距的。为了防止回流,我们只能取不大于C,而又最接近C的文件组合(对应图上的一对小箭头)。此处即是“背包问题”,当然了,为了简便,我并没有采用背包问题的解法,而是采取一种比较简单的,效果也比背包解法不会差太多的算法,即把所有第1分区中可被移动的文件按大小从大到小排,然后逐个判断,如果加进来不超过C则加进来,否则不加进来。最终会得到一个集合,这些就是真正要移动的文件。然后调用系统的移动文件的函数进行移动。

然后再来一次,重新找到新的highest,lowest,按同样的方法移动,直至没有一个文件可以移动,任务完成。

      核心的思想都讲了,以上解决了开头提出的问题一。至于问题二也好办,为准备接收文件的那个分区多预留一些空间就可以了。实施起来也简单,在获取该分区可用空间大小时故意减掉预留的数字就可以了。比如C,D,E,F 4个分区的可用空间都是2G,而准备接收一个4G的文件到F区,就为F预留4G的空间,目标结果是C,D,E可用空间变成1G,而F变成5G,总体可用空间还是8G,只不过F比别的多4G,这样就可以放下一个4G的文件了。实际情况F最终是4.xG、5.xG都有可能,总之会尽量地接近目标值5G。

2010-07-25 升级到1.0.3版,界面还是控制台形式,虽然许多人对此软件不感兴趣,我还是放出来供有需要的朋友下载:

v1.0.3  配置支付K,M,G,T等单位

下载: DiskBalance_v1_0_3.zip

 

posted @ 2010-05-22 23:39  BillySir  阅读(720)  评论(0编辑  收藏  举报