文件IO 文件属性获取,目录操作

文件属性获取

int stat(const char *path, struct stat *buf);
功能:获取文件属性

参数:
path:文件路径名
buf:保存文件属性信息的结构体

返回值:
成功:0
失败:-1

struct stat {
	ino_t     st_ino;     /* inode号 */
	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;   /* 最后状态改变时间 */
};

目录操作

//围绕目录流进行操作,DIR*

DIR *opendir(const char *name);
功能:获得目录流
参数:要打开的目录
返回值:
成功:目录流
失败:NULL

struct dirent *readdir(DIR *dirp);
功能:读目录
参数:要读的目录流
返回值:
成功:读到的信息    
败或读到目录结尾:NULL

返回值为结构体,该结构体成员为描述该目录下的文件信息
struct dirent {
ino_t   d_ino;               /* 索引节点号*/
off_t   d_off;               /*在目录文件中的偏移*/
unsigned short d_reclen;     /* 文件名长度*/
unsigned char  d_type;       /* 文件类型 */
char    d_name[256];         /* 文件名 */
};


int closedir(DIR *dirp);
功能:关闭目录
参数:dirp:目录流

使用上面的函数,结合帮助手册

想要查询stat可以使用下面命令

man 2 stat

想查看C语言函数库中的某个函数的手册,可以使用以下命令

man 3 函数名

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

void ls(const char *path) {
    DIR *dir;
    struct dirent *entry;
    struct stat file_stat;
    
    // 打开目录
    dir = opendir(path);
    if (dir == NULL) {
        perror("opendir");
        return;
    }
    
    // 读取目录中的文件
    while ((entry = readdir(dir)) != NULL) {
        // 获取文件的详细信息
        char file_path[256];
        sprintf(file_path, "%s/%s", path, entry->d_name);
        if (stat(file_path, &file_stat) == -1) {
            perror("stat");
            continue;
        }
        
        // 获取文件权限
        char perms[11];
        perms[0] = (S_ISDIR(file_stat.st_mode)) ? 'd' : '-';
        perms[1] = (file_stat.st_mode & S_IRUSR) ? 'r' : '-';
        perms[2] = (file_stat.st_mode & S_IWUSR) ? 'w' : '-';
        perms[3] = (file_stat.st_mode & S_IXUSR) ? 'x' : '-';
        perms[4] = (file_stat.st_mode & S_IRGRP) ? 'r' : '-';
        perms[5] = (file_stat.st_mode & S_IWGRP) ? 'w' : '-';
        perms[6] = (file_stat.st_mode & S_IXGRP) ? 'x' : '-';
        perms[7] = (file_stat.st_mode & S_IROTH) ? 'r' : '-';
        perms[8] = (file_stat.st_mode & S_IWOTH) ? 'w' : '-';
        perms[9] = (file_stat.st_mode & S_IXOTH) ? 'x' : '-';
        perms[10] = '\0';
        
        // 获取文件所有者
        struct passwd *pw = getpwuid(file_stat.st_uid);
        char *owner = (pw != NULL) ? pw->pw_name : "";
        
        // 获取文件所属组
        struct group *gr = getgrgid(file_stat.st_gid);
        char *group = (gr != NULL) ? gr->gr_name : "";
        
        // 获取文件大小
        off_t file_size = file_stat.st_size;
        
        // 获取文件最后修改时间
        char *time_str = ctime(&file_stat.st_mtime);
        time_str[strlen(time_str)-1] = '\0';  // 去除换行符
        
        // 打印文件信息
        printf("%s\t%ld\t%s\t%s\t%lld\t%s\n", perms, file_stat.st_nlink, owner, group, file_size, time_str);
    }
    
    // 关闭目录
    closedir(dir);
}

int main() {
    ls(".");  // 传入要列出文件的目录
    return 0;
}

 结果验证: