赞
踩
书上的说法是:
lstat与stat相同,除非是符号链接,统计链接本身,而不是链接所引用文件。所以,stat和lstat的区别是:stat遵循链接,但lstat不是
当初看这段话并没有真正理解,下面详细解释下:
首先,无论是stat
还是lstat
,对于硬链接文件,都将其视为regular文件,不同点只在于符号链接(symlink)文件。
对于stat(file, &mystat)
这个系统调用,无论是读取regular文件还是symlink文件,通过mystat.st_mode
获取到的文件类型都必然是regular文件,即S_ISREG(mystat.st_mode) == 1
。
对于lstat(file, &mystat)
这个系统调用,当file是symlink文件时,通过mystat.st_mode
获取到的文件类型是link文件,即S_ISLNK(mystat.st_mode) == 1
。
所以,当我们想要识别符号链接文件的时候,只能使用lstat
;当我们关注的是符号链接指向的文件时,就应该使用stat
。
下面展示mycp程序的一部分,file1是待复制的文件,file2是复制得到的文件。对于符号链接文件会创建对应的新符号链接,而不是简单的复制文件。对于reguler文件,会复制文件。
struct stat mystat; if(lstat(file1, &mystat) < 0){//must be lstat, not stat printf("stat %s fail\n", file1); exit(-1); } printf("%s st_mode is %x\n", file1, mystat.st_mode); if(S_ISLNK(mystat.st_mode)){ char linkName[FILE_NAME_LEN], fullLinkName[FILE_NAME_LEN]; strcpy(fullLinkName,file2); readlink(file1, linkName, FILE_NAME_LEN); for(int i=strlen(fullLinkName)-1;i>=0;i--){ if(fullLinkName[i] == '/'){ fullLinkName[i+1] = 0; break; } } strcat(fullLinkName, linkName); symlink(fullLinkName, file2); printf("link file %s to file %s\n", fullLinkName, file2); } else if(S_ISREG(mystat.st_mode)){ int oldFd = open(file1, O_RDONLY); int newFd = open(file2, O_RDWR | O_CREAT | O_TRUNC, 0664); int n=0; char buf[4096]; while(n = read(oldFd, buf, 4096)){ write(newFd, buf, n); } close(oldFd); close(newFd); printf("copy file %s to file %s\n", file1, file2); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。