linux回收站设计
linux回收站设计
在windows下有一个很好的东西,那就是回收站,虽然有很多人批评它。linux不是没有回收站,很多桌面环境都可以看到是有回收站的。
这里是讨论如何设计一个回收站,而不是有没有的问题。最好的结果是将rm
命令使用mv
命令替代使用了。
1、设计思路
因为在linux下rm
命令执行成功就直接将文件删除了,而不是将其移入回收站了,也没用给一个用于确认的命令提示,所以rm
的误操作是很危险的。而使用mv
命令来提供一个后悔机制,就挺好了。
我们可以设计这么一种操作,将rm
命令用mv
命令来改写,将要删除的文件,移动到一个隐藏的目录中。windows上的回收站就是这么做的,这是通常的做法。但是这还有一些问题,如下几点
1.文件同名问题。在一个目录下,不允许出现同名文件或者文件夹的问题。
2.恢复删除文件问题。如果只是简单的将要删除的文件移动到隐藏目录,那么就丢失了它原本所处的位置(路径)信息,不利于恢复到原目录。
3.不同分区问题。linux不同于windows,linux的目录结构并不体现出磁盘分区,所以单纯的根据文件路径不能确定其所在的分区。而如果不针对每个分区分设回收站,那么效率是很低的,因为不同分区间的文件移动,是会有拷贝过程的,而不仅仅只是目录项的操作。
2、设计思路问题分析
1、文件同名问题
文件同名的问题可以采取给文件编号的方式来解决。可以按照删除的顺序,给文件名加上一个数字前缀,这个数字从0开始,一直向上增加,就不会出现重复问题。对于这个数字,可以采取非十进制的设计来使得文件名更短小。比如说采取64进制的方式,以[0-9A-Za-z-_]这64个可见的可用于作为文件名的字符来作为前缀的"字符集",如果是64进制的话,那么需要的前缀长度可以选择固定长度,且不会很长。因为64=26,而232次方就已经大到42亿了,所以这里采用7或者8位就差不多足够了。对于整个文件夹删除的,仅仅对文件夹名加前缀就可以了。为了提高效率,还可以采取在前缀编号出现了空洞的时候(先删除了100个文件,又恢复了中间的20个,就出现了20个空洞的编号),采取不填补的原则,直接往后递增。当编号递增到最大值的时候,可以采取类似于磁盘整理的方式来进行前缀整理。
这里举一个例子,假设这里采取7位固定前缀。
删除的文件(夹)名 | 移动到回收站后的文件名 |
---|---|
a.txt | 0000000a.txt |
b.jpg | 0000001b.jpg |
...删除了多个文件后 | ... |
tree.c | 000001btree.c |
dir | 0000001cdir |
这样做后,恢复文件的时候,只要去掉其前缀就可以了。采用固定长度前缀是为了提高效率,这里有一个问题没有解决,就是文件名长度的问题。因为绝大多数的文件名长度都远远低于限制大小,所有这个问题影响不大。
2、恢复删除文件问题
这个问题也很好解决,配合上一个问题的思路来做。因为前面说了给每一个删除的文件都加上了固定不重复的前缀,而文件名不可能为空,所以我们可以采取添加一个文件来纪录原文件所在路径的方式来解决这个问题。
举个栗子:有一个文件在目录/home/xxx/code/c/test/
下,文件名是a.c
。删除到回收站后,编号为000000km
。那么这个文件删除到回收站后,将其文件名改为000000kma.c
,那么再建立一个文件000000km
这个文件的内容就是/home/xxx/code/c/test
。这么做就保存了文件所在的原本路径,恢复的时候根据这个路径来恢复就是了。
3、不同分区问题
这个问题要解决也不难,就是针对各个分区设立回收站嘛。主要问题在于获取文件或者文件夹所在的分区。这个不难,可以通过df -h
来获取各个分区的挂载点,然后对文件或目录的路径来比对得出其所在的分区即可。这里的一个问题是要不要为了提高效率而存储各个分区挂载路径的结果呢?我觉得是不需要的,使用df -h
命令的成本并不高,而且不会涉及到分区卸载后再挂载到另外目录的情况。