在文件处理中经常用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:路径名中有不是目录的存在
用代码说话,焦点访谈~~~
- #include <stdio.h>
-
#include <stdlib.h>
-
#include <fcntl.h>
-
#include <unistd.h>
-
#include <sys/stat.h>
-
#include <sys/types.h>
-
#include <string.h>
-
#include <dirent.h>
-
#include <errno.h>
-
/*
-
实现cp命令,v2
-
*/
-
-
#define fore 0001
-
int flags=0;
-
void print_help()
-
{
-
printf("mycp [-f] filename1 filename2\n");
-
}
-
-
char *getnewpath(char *pathname,char *concat)
-
{
-
char *newpath;
-
char c=pathname[strlen(pathname)-1];
-
newpath=(char *)malloc(strlen(pathname)+strlen(concat)+1+(
-
if(newpath==NULL)
-
{
-
perror("memery malloc:");
-
exit(0);
-
}
-
sprintf(newpath,"%s%s%s",pathname,c=='/' ? "":"/",concat);
-
return newpath;
-
}
-
int cp(char *dest,char *src,int flags)
-
{
-
char buff[1024];
-
int fddest,fdsrc;
-
char *newsrc,*newdest;
-
bool destexist=true; //目标文件是否已存在
-
DIR *dp;
-
struct dirent *dir;
-
struct stat srcstat,deststat;
-
int relen=0,wrlen=0;
-
if(lstat(src,&srcstat)<0)
-
{
-
perror(src);
-
exit(0);
-
}
-
if(lstat(dest,&deststat)<0)
-
{
-
if(errno!=ENOENT)
-
{
-
return 0;
-
}
-
destexist=false;
-
}
-
-
if(S_ISDIR(srcstat.st_mode)) //目录
-
{
-
if(!destexist)
-
{
-
if(mkdir(dest,srcstat.st_mode)<0) //按src的权限建目录
-
{
-
perror("can't create ");
-
return 0;
-
}
-
}
-
else if(!S_ISDIR(deststat.st_mode))
-
{
-
printf("%s not a diretory",dest);
-
return 0;
-
}
-
if((dp=opendir(src))==NULL)
-
{
-
perror(src);
-
return 0;
-
}
-
while((dir=readdir(dp))!=NULL)
-
{
-
if(strcmp(dir->d_name,".")==0||strcmp(dir->d_name,"..")==0)
-
continue;
-
newsrc=getnewpath(src,dir->d_name);
-
newdest=getnewpath(dest,dir->d_name);
-
cp(newdest,newsrc,flags);
-
free(newdest);
-
free(newsrc);
-
}
-
}
-
-
if(S_ISREG(srcstat.st_mode)) //普通文件
-
{
-
if(destexist&& !(flags&fore)) //覆盖?
-
{
-
int ch;
-
printf("file %s is exist cover it ?[n/y] ",dest);
-
while(ch=getchar())
-
{
-
if(ch=='y'||ch=='Y')
-
break;
-
if(ch=='n'||ch=='N')
-
exit(0);
-
else
-
printf("please input [n/y] :");
-
getchar(); //接收回车字符
-
}
-
}
-
-
if ((fdsrc=open(src,O_RDONLY))==-1)
-
{
-
perror(src);
-
return 0;
-
}
-
if ((fddest=open(dest,O_WRONLY|O_TRUNC|O_CREAT,srcstat.st_mode))==-1)
-
{
-
perror(dest);
-
return 0;
-
}
-
while ((relen=read(fdsrc,buff,sizeof(buff))) > 0)
-
{
-
if (write(fddest,buff,relen)==-1)
-
{
-
perror("error:");
-
return 0;
-
}
-
memset(buff,0,sizeof(buff));
-
}
-
if (relen==-1)
-
{
-
perror("error:");
-
return 0;
-
}
-
}
-
close(fdsrc);
close(fddest); - return 0;
-
}
-
-
void args_cmd(int argc,char **argv,char *dest,char *src,int flags)
-
{
-
int i,j;
-
int ch;
-
while((ch=getopt(argc,argv,"f"))!=-1)
-
{
-
switch(ch)
-
{
-
case 'f':
-
flags |=fore;
-
break;
-
default:
-
printf("invaild option %c\n",ch);
-
print_help();
-
exit(0);
-
}
-
}
-
if(optind+2!=argc||argc==2)
-
{
-
print_help();
-
exit(0);
-
}
-
strcpy(src,argv[optind]);
-
strcpy(dest,argv[optind+1]);
-
return;
-
}
-
-
int main(int argc,char **argv)
-
{
-
char src[128],dest[128];
-
args_cmd(argc,argv,dest,src,flags);
-
cp(dest,src,flags);
-
return 0;
-
}
阅读(2158) | 评论(0) | 转发(0) |