目录
stat函数
获取文件属性
获取文件权限
实现“head -n 文件名”命令的功能
编程实现“ls -l 文件名”功能
stat/fstat/lstat的区别?
stat函数
int stat(const char *path, struct stat *buf);
功能:获取文件属性
参数: path:文件路径名buf:保存文件属性信息的结构体
返回值:成功:0失败:-1struct stat {ino_t st_ino; /* inode号 ls -il */ mode_t st_mode; /* 文件类型和权限 */nlink_t st_nlink; /* 硬链接数 */uid_t st_uid; /* 用户ID */gid_t st_gid; /* 组ID */off_t st_size; /* 大小 */time_t st_atime; /* 最后访问时间 */time_t st_mtime; /* 最后修改时间 */time_t st_ctime; /* 最后状态改变时间 */};
打印inode号,链接数,大小:
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int main(int argc, char const *argv[])
{struct stat st;if(stat("a.c",&st)<0){perror("stat err");return -1;}printf("inode:%lu nlink:%d size:%ld\n",st.st_ino,st.st_nlink,st.st_size);return 0;
}
获取文件属性
S_IFMT是一个掩码,它的值是0170000(注意这里用的是八进制前缀为0,二进制为0b1111000000000000), 可以用来过滤出四位表示的文件类型
例如:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int main(int argc, char const *argv[])
{struct stat st;if (stat(".", &st) < 0){perror("stat err");return -1;}printf("inode:%lu nlink:%d size:%ld\n", st.st_ino, st.st_nlink,st.st_size);printf("%#o\n", st.st_mode);//判断文件类型if ((st.st_mode & __S_IFMT) == __S_IFREG)printf("regular file\n");else if ((st.st_mode & __S_IFMT) == __S_IFDIR)printf("directory\n");//或者用宏函数if (S_ISREG(st.st_mode))printf("-");else if (S_ISDIR(st.st_mode))printf("d");return 0;
}
获取文件权限
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int main(int argc, char const *argv[])
{struct stat st;if (stat(".", &st) < 0){perror("stat err");return -1;}printf("inode:%lu nlink:%d size:%ld\n", st.st_ino, st.st_nlink,st.st_size);printf("%#o\n", st.st_mode);//判断文件权限//个人权限if (st.st_mode & S_IRUSR)putchar('r');elseputchar('-');if (st.st_mode & S_IWUSR)putchar('w');elseputchar('-');if (st.st_mode & S_IXUSR)putchar('x');elseputchar('-');return 0;
}
实现“head -n 文件名”命令的功能
例:head -3 test.c -> ./a.out -3 test.c
atoi : "1234" -- 1234
思路:1. 打开文件 2. 获取到行数 3.循环读,读到内容判断\n则n++,打印。4. 直到n为行数则停止
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{FILE *fp;int num, n = 0;char buf[32] = "";if (argc != 3){printf("Usage: %s -n <file>\n", argv[0]);return -1;}fp = fopen(argv[2], "r");if (fp == NULL){perror("fopen err");return -1;}num = atoi(argv[1] + 1); //./a.out -3 a.c,+1是为了去掉-if (num == 0) //判断-0的情况return 0;while (fgets(buf, 32, fp)) //或者fgets(buf,32,fp)!=NULL{//如果最后一个是换行则,行数加一。if (buf[strlen(buf) - 1] == '\n')n++;//先打印,之后如果达到所记录行数则终止循环。printf("%s", buf);if (num == n)break;}fclose(fp);return 0;
}
编程实现“ls -l 文件名”功能
getpwuid
getgrgid
localtime或ctime
ctime函数在C库中,头文件为<time.h>
函数原型:
char *ctime (const time_t *__timer)
作用:返回一个表示当地时间的字符串,当地时间是基于参数 timer
格式例如: Wed Aug 29 19:48:54 2018
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>int main(int argc, char const *argv[])
{struct stat st;if (stat(argv[1], &st) < 0){perror("stat err");return -1;}//判断文件类型switch (st.st_mode & S_IFMT){case S_IFREG:printf("-");break;case S_IFDIR:printf("d");break;case S_IFCHR:printf("c");break;case S_IFIFO:printf("f");break;case S_IFLNK:printf("l");break;case S_IFBLK:printf("b");break;case S_IFSOCK:printf("s");break;default:printf("mode err\n");break;}//判断文件权限//个人权限if (st.st_mode & S_IRUSR)printf("r");elseprintf("-");if (st.st_mode & S_IWUSR)printf("w");elseprintf("-");if ((st.st_mode & S_IXUSR))printf("x");elseprintf("-");//小组权限if (st.st_mode & S_IRGRP)printf("r");elseprintf("-");if (st.st_mode & S_IWGRP)printf("w");elseprintf("-");if ((st.st_mode & S_IXGRP))printf("x");elseprintf("-");//其他人权限if (st.st_mode & S_IROTH)printf("r");elseprintf("-");if (st.st_mode & S_IWOTH)printf("w");elseprintf("-");if ((st.st_mode & S_IXOTH))printf("x");elseprintf("-");//链接数printf(" %d",st.st_nlink);//用户名 用getpwuid函数printf(" %s",getpwuid(st.st_uid)->pw_name);//组名 用getgrgid函数printf(" %s",getgrgid(st.st_gid)->gr_name);//文件大小printf(" %ld",st.st_size);//最后修改时间printf(" %.12s",ctime(&st.st_mtime)+4); //+4是为了跳过前4位(偏移4个地址), .12是为了只打印12个字符//名字printf(" %s\n",argv[1]);return 0;
}
stat/fstat/lstat的区别?
stat函数返回一个与此命名文件有关的信息结构
fstat函数获得已在描述符filedes上打开的文件的有关信息,也就是参数是文件描述符,其他与stat相同。
lstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息.