Chinaunix首页 | 论坛 | 博客
  • 博客访问: 279219
  • 博文数量: 95
  • 博客积分: 618
  • 博客等级: 中士
  • 技术积分: 455
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-28 13:39
文章分类

全部博文(95)

文章存档

2015年(65)

2013年(1)

2012年(10)

2011年(19)

分类: C/C++

2011-12-08 23:34:31

在文件处理中经常用lstat函数,用来获取文件相关信息。
int lstat(const char *path, struct stat *buf);
path:文件路径名
buf:存放文件信息的结构体指针
出错返回-1,出错信息在errno中

用man看一下,现在连蔡依琳都会唱 I need a real man了,可见man的重要性~~~可惜英语不那么好,还要靠google同志搭救~~
struct stat {   
                    dev_t st_dev; /* 文件所在设备的标识 */   
                    ino_t st_ino; /* 文件结点号 */   
                    mode_t st_mode; /* 文件保护模式 */   
                    nlink_t st_nlink; /* 硬连接数 */   
                    uid_t st_uid; /* 文件用户标识 */   
                    gid_t st_gid; /* 文件用户组标识 */   
                    dev_t st_rdev; /* 文件所表示的特殊设备文件的设备标识 */   
                    off_t st_size; /* 总大小,字节为单位 */   
                    blksize_t st_blksize; /* 文件系统的块大小 */   
                    blkcnt_t st_blocks; /* 分配给文件的块的数量,512字节为单元 */   
                    time_t st_atime; /* 最后访问时间 */   
                    time_t st_mtime; /* 最后修改时间 */   
                    time_t st_ctime; /* 最后状态改变时间 */   
};
 用st_mode测试文件类型
           S_ISREG(m) 普通文件?
           S_ISDIR(m)  目录?
           S_ISCHR(m)  字符设备?
           S_ISBLK(m)  块设备?
           S_ISFIFO(m) 管道?
           S_ISLNK(m)  符号链接?
           S_ISSOCK(m) socket?

errno的值可能是
           EBADF:  fd is bad.
           EFAULT: Bad address.
           ELOOP: 符号连接太多  
           ENAMETOOLONG:文件名太长   
           ENOENT:文件不存在,或名字是空字符串   
           ENOMEM:内存不足   
           ENOTDIR:路径名中有不是目录的存在

用代码说话,焦点访谈~~~
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <sys/stat.h>
  6. #include <sys/types.h>
  7. #include <string.h>
  8. #include <dirent.h>
  9. #include <errno.h>
  10. /*
  11. 实现cp命令,v2
  12. */

  13. #define fore 0001
  14. int flags=0;
  15. void print_help()
  16. {
  17.     printf("mycp [-f] filename1 filename2\n");
  18. }

  19. char *getnewpath(char *pathname,char *concat)
  20. {
  21.     char *newpath;
  22.     char c=pathname[strlen(pathname)-1];
  23.     newpath=(char *)malloc(strlen(pathname)+strlen(concat)+1+(
  24.     if(newpath==NULL)
  25.     {
  26.         perror("memery malloc:");
  27.         exit(0);
  28.     }
  29.     sprintf(newpath,"%s%s%s",pathname,c=='/' ? "":"/",concat);
  30.     return newpath;
  31. }
  32. int cp(char *dest,char *src,int flags)
  33. {
  34.     char buff[1024];
  35.     int fddest,fdsrc;
  36.     char *newsrc,*newdest;
  37.     bool destexist=true; //目标文件是否已存在
  38.     DIR *dp;
  39.     struct dirent *dir;
  40.     struct stat srcstat,deststat;
  41.     int relen=0,wrlen=0;
  42.     if(lstat(src,&srcstat)<0)
  43.     {
  44.         perror(src);
  45.         exit(0);
  46.     }    
  47.     if(lstat(dest,&deststat)<0)
  48.     {
  49.         if(errno!=ENOENT)
  50.         {
  51.             return 0;
  52.         }
  53.         destexist=false;
  54.     }

  55.     if(S_ISDIR(srcstat.st_mode)) //目录
  56.     {
  57.         if(!destexist)
  58.         {
  59.             if(mkdir(dest,srcstat.st_mode)<0) //按src的权限建目录
  60.             {
  61.                 perror("can't create ");
  62.                 return 0;
  63.             }
  64.         }
  65.         else if(!S_ISDIR(deststat.st_mode))
  66.         {
  67.             printf("%s not a diretory",dest);
  68.             return 0;
  69.         }
  70.         if((dp=opendir(src))==NULL)
  71.         {
  72.             perror(src);
  73.             return 0;
  74.         }
  75.         while((dir=readdir(dp))!=NULL)
  76.         {
  77.              if(strcmp(dir->d_name,".")==0||strcmp(dir->d_name,"..")==0)
  78.                 continue;
  79.             newsrc=getnewpath(src,dir->d_name);
  80.             newdest=getnewpath(dest,dir->d_name);
  81.             cp(newdest,newsrc,flags);
  82.             free(newdest);
  83.             free(newsrc);
  84.         }
  85.     }
  86.     
  87.     if(S_ISREG(srcstat.st_mode)) //普通文件
  88.     {
  89.         if(destexist&& !(flags&fore)) //覆盖?
  90.         {
  91.             int ch;
  92.             printf("file %s is exist cover it ?[n/y] ",dest);
  93.             while(ch=getchar())
  94.             {
  95.                 if(ch=='y'||ch=='Y')
  96.                     break;
  97.                 if(ch=='n'||ch=='N')
  98.                     exit(0);
  99.                 else
  100.                     printf("please input [n/y] :");
  101.                 getchar(); //接收回车字符
  102.             }
  103.         }
  104.         
  105.         if ((fdsrc=open(src,O_RDONLY))==-1)
  106.         {
  107.             perror(src);
  108.                         return 0;
  109.         }
  110.         if ((fddest=open(dest,O_WRONLY|O_TRUNC|O_CREAT,srcstat.st_mode))==-1)
  111.         {
  112.             perror(dest);
  113.                         return 0;
  114.         }
  115.         while ((relen=read(fdsrc,buff,sizeof(buff))) > 0)
  116.         {
  117.             if (write(fddest,buff,relen)==-1)
  118.             {
  119.                 perror("error:");
  120.                                 return 0;
  121.             }
  122.             memset(buff,0,sizeof(buff));
  123.         }
  124.         if (relen==-1)
  125.         {
  126.             perror("error:");
  127.                         return 0;
  128.         }
  129.     }        
  130.     close(fdsrc);            
        close(fddest);
  131.     return 0;
  132. }

  133. void args_cmd(int argc,char **argv,char *dest,char *src,int flags)
  134. {
  135.     int i,j;
  136.     int ch;
  137.     while((ch=getopt(argc,argv,"f"))!=-1)
  138.     {
  139.         switch(ch)
  140.         {
  141.             case 'f':
  142.                 flags |=fore;
  143.                 break;
  144.             default:
  145.                 printf("invaild option %c\n",ch);
  146.                 print_help();
  147.                 exit(0);
  148.         }
  149.     }
  150.     if(optind+2!=argc||argc==2)
  151.     {
  152.         print_help();
  153.         exit(0);
  154.     }
  155.     strcpy(src,argv[optind]);
  156.     strcpy(dest,argv[optind+1]);
  157.     return;
  158. }

  159. int main(int argc,char **argv)
  160. {
  161.     char src[128],dest[128];
  162.     args_cmd(argc,argv,dest,src,flags);
  163.     cp(dest,src,flags);
  164.     return 0;
  165. }


阅读(2118) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~