一、文件与目录属性 ---->学习用函数实现ls -l功能
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat (const char *pathname , struct stat *statbuf)//如果文件为符号链接文件(软链接),则返回本体文件信息
int fstat (int fd ,struct stat * statbuf)//需要先打开文件获取文件描述符,才可以获取文件属性
int lstat (const char *pathname ,struct stat *statbuf)//如果文件为符号链接文件,则会返回符号链接文件的文件属性
*返回值:成功返回0,失败返回-1,并设置错误码
参数:pathname 路径
struct stat*statbuf 系统定义结构体
struct stat {
dev_t st_dev; /* ID of device containing file */
设备文件
ino_t st_ino; /* Inode number */
inode索引码
mode_t st_mode; /* File type and mode */***!
文件类型与权限
nlink_t st_nlink; /* Number of hard links */
硬链接数
uid_t st_uid; /* User ID of owner */
文件拥有者ID
gid_t st_gid; /* Group ID of owner */
文件所属组ID
dev_t st_rdev; /* Device ID (if special file) */
设备号
off_t st_size; /* Total size, in bytes */
文件大小
blksize_t st_blksize; /* Block size for filesystem I/O */
块大小
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
块数
struct timespec st_atim; /* Time of last access */
最后访问时间
struct timespec st_mtim; /* Time of last modification */
最后修改时间
struct timespec st_ctim; /* Time of last status change */
文件状态最后更改时间
#define st_atime st_atim . tv_sec /* Backward compatibility */
#define st_mtime st_mtim . tv_sec
#define st_ctime st_ctim . tv_sec
};
#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespec *tp);
参数:clockid_t: 用于指定计时时钟的类型(自己搜索)
struct timespec {
time_t tv_sec; // seconds
long tv_nsec; // and nanoseconds
};
--------------------------------------------------------
通过ID转化为文件拥有者和文件所属组
struct passwd *getpwuid(uid_t uid);
struct passwd {
char *pw_name; /* username */ 文件拥有者名称
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
所属组
struct group *getgrgid(gid_t gid);
struct group {
char *gr_name; /* group name */ 组名
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* NULL-terminated array of pointersto names of group members */
};
可以用以下的宏确定文件类型。这些宏的参数都是struct stat结构中的st_mode成员。 S_ISREG(m) is it a regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_ISBLK(m) block device?
S_ISFIFO(m) FIFO (named pipe)?
S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(m) socket? (Not in POSIX.1-1996
-------------------------------------
例子:
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
int main(int argc,char *argv[]){
if(argc<2){
printf("User:%s <read_file>\n",argv[0]);
return -1;
}
//声明区
struct stat st;
int i;
char *str="xwr-";
//调用函数,启用结构体,就会把argv[1]的文件信息,赋予到结构体st中
//接下来要做的操作就是把st结构体里的东西提取出来
if(lstat(argv[1],&st)<0){
perror("lstat error");
return -1;
}
//文件类型
if(S_ISREG(st.st_mode))//判断常规文件
printf("-");
else if(S_ISDIR(st.st_mode))//判断目录
printf("d");
else if(S_ISCHR(st.st_mode))//判断设备
printf("c");
else if(S_ISBLK(st.st_mode))//判断块设备
printf("b");
else if(S_ISFIFO(st.st_mode))//判断管道---多进程线程
printf("p");
else if(S_ISLNK(st.st_mode))//判断软连接
printf("l");
else if(S_ISSOCK(st.st_mode))//判断套接字--网络编程
printf("s");
//文件权限
for(i=8;i>=0;i--){
if(st.st_mode &1 << i) //左移操作
printf("%c",str[i%3]);
else
printf("%c",str[3]);
}
//硬连接数
printf(" %ld ",st.st_nlink);
//文件拥有者和文件所属组
//两种方式:1>正儿八经式
//1>正儿八经式:(整合版本)
printf("%s ",getpwuid(st.st_uid)->pw_name);
printf("%s ",getgrgid(st.st_gid)->gr_name);
/*(分离版本)
struct passwd *pd=getpwuid(st.st_uid);
printf("%s ",pd->pw_name);
*/
//文件大小
printf("%ld ",st.st_size);
//打印文件最后修改时间 而且时间具有:月 日 时:分
//通过localtime函数自定义时间格式
struct tm *tp=localtime(&st.st_mtime);
printf("%d月 %d %d:%d ",tp->tm_mon+1,tp->tm_mday,tp->tm_hour,tp->tm_min);
//打印文件名
printf("%s\n",argv[1]);
return 0;
}