饮水思源收藏夹多级目录的实现细节

发表于:2007-07-04来源:作者:点击数: 标签:
这一个多周说起来做的事情还蛮多的,回家呆了3天,飞来飞去,然后写了2天web的收藏夹,写好了本来想偷懒了,结果最后还是把任务摊到自己头上了,结果又写了2天的te .net 代码,感觉多写些代码实在有好处,至少写完了不会有语法错误,也不会出现什么没定义,或
这一个多周说起来做的事情还蛮多的,回家呆了3天,飞来飞去,然后写了2天web的收藏夹,写好了本来想偷懒了,结果最后还是把任务摊到自己头上了,结果又写了2天的te.net代码,感觉多写些代码实在有好处,至少写完了不会有语法错误,也不会出现什么没定义,或者函数用错的情况,对了有个很郁闷的事情,就是关于calloc函数,我从网上down下来的一个资料时说calloc(n,size),结果错误不断,排除了各种问题之后,才知道原来竟然是calloc(size,n),浪费半天时间啊,没有任何进展,很是郁闷。废话不多说,说一下我是如何实现任意文件夹以及任意讨论区的。

收藏家的struct
//added by kongyang 2006-06-28
struct boardcollection
{
    int subnum;//the number of subdirectories not includes dirs in extends
    int boardnum;//the number of boards
    int isextends;//0 stands for being not an extends,1 not
    char subdirsfile[20][32];//one dir can have 20 sub dirs, this stores the
filename of each subs
    char subdirname[20][32];//names
    char boards[20][32];//can have 20 boards
    char dirname[32];//filename of current dir
    char updir[32];//the filename of father dir
    char extends[32];//extends of subdirectories.
};
subnum是当前文件的子目录数目,但是不包含扩展目录下面的子目录数目
也就是说,当前文件的子目录总数应该是它现在的包含的子目录数目还有扩展
以及可能的扩展的扩展的包含的子目录数目总和。
boardnum是当前文件的版面数目,当然也不包含扩展文件下的字文件夹数目
也就是说,如果要统计当前的总目录或者文件夹数目的话,用这个函数:
int getgood_dirnum(struct boardcollection currentdir)
{
    int i=0;
    i+=currentdir.subnum;
    while(currentdir.extends[0]!=0)
    {
        f_get_file(currentdir.extends, &currentdir, 1);
        i+=currentdir.subnum;
    }
    return i;
}
isextends代表当前的这个文件是否是某一个文件的扩展

f_get_file为从一个文件中获得一个结构体
subdirsfile为对应子目录名字的文件名
subdisname为子目录的显示给用户的名字
boards是讨论区的名字
dirname是当前文件所在的文件名
updir是父文件夹的文件名
extends为除了20各目录和20各讨论区后,是否要添加扩展,以实现任意多的讨论区
和任意多的文件夹

这只是一个实现策略,没有去参考别人的,本来水母也实现了这个功能,但是还是想有点自己的知识产权,所以全部自己来构造。一开始思维会比较混乱,觉得extends的文件和当前目录的关系不好把握。

后来慢慢写得多了,思路也清晰了。目录确定了以后,就是来进行添加删除目录了。其实添加也很简单,看看当前目录有没有空余的空间,有的话就直接架上,没有的话就放到extends里面,extends满了再放到

extends的extends里面...贴一段函数如下

int do_adddir(char *boardfile,char* newdir)
{
 char boardfilename[80];
 struct boardcollection currentdir;
 struct boardcollection newstruct;
 time_t now;
 get(boardfilename);
 f_get_file(boardfile, &currentdir, 1);
 if(currentdir.subnum<20)
 {
  now=getfilename();
  currentdir.subnum++;
  snprintf(currentdir.subdirsfile[currentdir.subnum-1],80,"%d",now);
  snprintf(currentdir.subdirname[currentdir.subnum-1],80,"%s",newdir);
  f_replace_file(currentdir);
  init_dir(&newstruct,currentdir.subdirsfile[currentdir.subnum-1],boardfile);
  f_replace_file(newstruct);
 }
 else
 {
  if(currentdir.extends[0]==0)
  {
   now=getfilename();
   snprintf(currentdir.extends,80,"%d",now);
   f_replace_file(currentdir);
   init_dir(&newstruct,currentdir.extends,boardfile);
   newstruct.isextends=1;
   f_replace_file(newstruct);
   do_adddir(currentdir.extends,newdir);
  }
  else
  {
   do_adddir(currentdir.extends,newdir);
  }
 }
 return 0;
 
}

写起来的一个很大的感觉就是要多用函数,把相同的操作尽量封装到汉书里面,这样写起程序来也会感觉很帅,而且也很容易定位错误。更重要的是大大的降低了代码的复杂度,提高了代码的可读性。

然后删除的时候会比较麻烦一点,因为删除一个目录,已开始想得很多,结果走了半个小时的弯路,后来猛一回神,发现是如此简单,只要把想删除的文件里的信息读出来,然后删除子目录对应的文件,

当然在芟除这些文件之前,要先读出子目录对应的文件里包含的子目录的文件,如此下去,就ok了,已开始总是在想,删除了子目录,父目录会受到什么影响?比如是extends的话有可能不包含子目录了那么这个extends

的生命就结束了等等,后来才发现不需要每个删除都要考虑这一点的,已开始得知需要删除no care就好了,要考虑的只是最上层这个的情况,贴函数如下

int do_deldir(struct boardcollection updir,char *deldir)
{
 struct boardcollection dirr;
 struct boardcollection upupdir;
 f_get_file(deldir, &dirr,1);
 do_del_nocare(dirr);
 struct_del_dir(&updir,deldir);
 if(updir.isextends==1&&updir.boardnum==0&&updir.subnum==0)
 {
  if(updir.extends[0]==0)
  {
   f_get_file(updir.updir,&upupdir,1);
   upupdir.extends[0]=0;
   f_replace_file(upupdir);
  }
  else
  {
   f_get_file(updir.updir,&upupdir,1);
   snprintf(upupdir.extends,80,"%s",updir.extends);
   f_replace_file(upupdir);
  }
  removefile(updir.dirname);
 }
 else
 {
  f_replace_file(updir);
 }
 return 0;
 
}

大体来说就是这些了,其他的如果要向编写一个好的程序的话,良好的编程风格是需要的,还有,头脑一定要清楚你干的是什么?要多思考,因为,很有可能,某些架构已开始就错误了,后来有可能就走不下去了

一定要想得细致周到

大概就获得这些经验吧,对了,还研究了一些javascript的语法,php的相关知识,配置了一下apache服务器,感觉还是蛮清楚地

原文转自:http://www.ltesting.net