函数stat、fstat、lstat
这三个函数的功能是一致的,都用于获取文件相关信息,但应用于不同的文件对象。对于函数中给出pathname参数,stat函数返回与此命名文件有关的信息结构,fstat函数获取已在描述符fields上打开文件的有关信息,lstat函数类似于stat但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用文件的信息。
函数原型
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
path:文件路径名。
fd:文件描述符。
buf:是以下结构体的指针
以上三个函数:成功返回0,失败返回-1,并且将详细错误信息赋值给errno全局变量。
stat、lstat和fstat函数中 struct stat类型的说明:
struct stat {
dev_t st_dev; /* 文件的设备编号 */
ino_t st_ino; /* 索引结点编号 */
mode_t st_mode; /* 文件类型和权限*/
nlink_t st_nlink; /*硬链接数 */
uid_t st_uid; /*用户ID*/
gid_t st_gid; /* 组ID*/
dev_t st_rdev; /* 设备类型(若此文件为设备文件,则为设备编号*/
off_t st_size; /* 文件大小*/
blksize_t st_blksize; /*文件系统的I/O缓冲区大小*/
blkcnt_t st_blocks; /* 块数 */
time_t st_atime; /* 访问时间 */
time_t st_mtime; /* 修改时间 */
time_t st_ctime; /* 更改时间 */
};
mode_t st_mode; /* 文件类型和权限*/
st_mode变量(mode_t类型):该变量占 2byte共16位,为16位的整型值。用于储存文件类型和权限。 如下图所示:
测试程序
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
if(argc<2)
printf("./statuse filename1 filename2 ..\n");
struct stat zsx;
int ret;
for(int i=1;i<argc;i++)
{
ret = stat(argv[i],&zsx);
if(ret==-1)
printf("stat error!");
else{
int g = (int)zsx.st_size;
printf("%d\n",g);
}
}
}
利用stat自制命令selfls
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<dirent.h>
#include<pwd.h>
#include<time.h>
#include<grp.h>
#include<string.h>
//#define FILEPATH "/home/linli/大三上/Unix系统程序设计/experiments"
#define MAX_PATH 1024
//FILEPATH = (char*)malloc(sizeof(char)*1000);
void ls(char *d_name)
{
struct stat buf;
int ret;
// printf("%s",d_name);
ret = stat(d_name,&buf);
if(ret == -1){
// printf("stat error");
// exit(0);
}
char perms[11] = {0};
if(S_ISLNK(buf.st_mode)){
perms[0] = 'l';
}
else if (S_ISDIR(buf.st_mode)){
perms[0] = 'd';
}
else if(S_ISBLK(buf.st_mode)){
perms[0] = 'b';
}
else if(S_ISCHR(buf.st_mode)){
perms[0] = 'c';
}
else if(S_ISSOCK(buf.st_mode)){
perms[0] = 's';
}
else if(S_ISFIFO(buf.st_mode)){
perms[0] = 'p';
}
else{
perms[0]='?';
}
perms[1] = (buf.st_mode & S_IRUSR) ? 'r' : '-';
perms[2] = (buf.st_mode & S_IWUSR) ? 'w' : '-';
perms[3] = (buf.st_mode & S_IXUSR) ? 'x' : '-';
perms[4] = (buf.st_mode & S_IRGRP) ? 'r' : '-';
perms[5] = (buf.st_mode & S_IWGRP) ? 'w' : '-';
perms[6] = (buf.st_mode & S_IXGRP) ? 'x' : '-';
perms[7] = (buf.st_mode & S_IROTH) ? 'r' : '-';
perms[8] = (buf.st_mode & S_IWOTH) ? 'w' : '-';
perms[9] = (buf.st_mode & S_IXOTH) ? 'x' : '-';
int linkNum = buf.st_nlink;
char* fileUser = getpwuid(buf.st_uid)->pw_name;
char* fileGrp = getgrgid(buf.st_gid)->gr_name;
int fileSize = (int)buf.st_size;
char* time = ctime(&buf.st_mtime);
char mtime[512]={0};
strncpy(mtime,time,strlen(time)-1);
char buff[1024];
sprintf(buff,"%s %d %s %s %d %s %s",perms,linkNum,fileUser,fileGrp,fileSize,mtime,d_name);
printf("%s\n",buff);
}
int main(int argc,char *argv[] )
{
struct dirent *entry;
DIR *dir = NULL;
char buffer[MAX_PATH];
getcwd(buffer,MAX_PATH);
printf("The current directory is: %s\n",buffer);
dir = opendir(buffer);
if(dir==NULL)
{
printf("opendir failed!");
exit(0);
}
else{
while(entry=readdir(dir))
{
ls(entry->d_name);
// printf("OK");
}
closedir(dir);
}
return 0;
}