readdir()& stat() & strftime()

readdir()

DIR *opendir(const char *name); 
//函数的作用是:打开与目录名对应的目录流,并返回指向目录流的指针(目录中的第一个信息)。
#include <dirent.h>
struct dirent *readdir(DIR *dirp);

//On Linux, the dirent structure is defined as follows:
    struct dirent
	{
	   long d_ino;               /* inode number 索引节点号 */
	   off_t d_off;              /* offset to this dirent 在目录文件中的偏移 */
	   unsigned short d_reclen;  /* length of this d_name 文件名长 */
	   unsigned char d_type;     /* the type of d_name 文件类型 */
	   char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
	}

函数的作用是:返回一个指向dirent结构体的指针,该结构体表示参数dirp指向的目录流中的下一个目录项。它在到达目录流的末尾或发生错误时返回NULL。
返回值:成功时,readdir()返回指向dirent结构的指针,如果到达目录流的末尾,则返回NULL,并且不会更改errno。如果发生错误,则返回NULL并适当设置errno。

//使用
DIR *dp = opendir(src);		//打开目录src,并拷贝到(DIR定义)目录dp
struct dirent *dirp;		//dirp指向结构dirent(dirp命名自定义)
dirp = readdir(dp);			//返回参数dp目录流的下个目录进入点
dirp -> d_name;				//通过dirp 指向(->)文件名(d_name),从而获取dp/src的文件名

stat()

#include <sys/types.h>    
#include <sys/stat.h> 
#include <unistd.h>

int stat(const char *path, struct stat *buf);

//其中stat结构包含以下字段:
struct stat  
{   
    dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/  
    ino_t       st_ino;     /* inode number -inode节点号*/    
    mode_t      st_mode;    /* protection -保护模式?*/    
    nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/    
    uid_t       st_uid;     /* user ID of owner -user id*/    
    gid_t       st_gid;     /* group ID of owner - group id*/    
    dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/    
    off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/    
    blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/    
    blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/    
    time_t      st_atime;   /* time of last access -上次存取时间*/    
    time_t      st_mtime;   /* time of last modification -上次修改时间*/    
    time_t      st_ctime;   /* time of last status change - 创建时间*/    
};  

功能:根据文件路径填充文件的stat结构信息。
成功时,返回零。出现错误时,返回-1并适当设置errno。

//最多的属性是st_mode.通过着属性我们可以判断给定的文件是一个普通文件还是一个目录,连接等等.可以使用下面几个宏来判断:
	S_ISLNK(st_mode)是否是一个连接.
	S_ISREG(st_mode)是否是一个常规文件.
	S_ISDIR(st_mode)是否是一个目录
	S_ISCHR(st_mode)是否是一个字符设备.
	S_ISBLK(st_mode)是否是一个块设备
	S_ISFIFO(st_mode)是否是一个FIFO文件.
	S_ISSOCK(st_mode)是否是一个SOCKET文件.
	
//The following flags are defined for the st_mode field:
    S_IFMT     0170000   bit mask for the file type bit fields
    S_IFSOCK   0140000   socket
    S_IFLNK    0120000   symbolic link
    S_IFREG    0100000   regular file
    S_IFBLK    0060000   block device
    S_IFDIR    0040000   directory
    S_IFCHR    0020000   character device
    S_IFIFO    0010000   FIFO
    S_ISUID    0004000   set-user-ID bit
    S_ISGID    0002000   set-group-ID bit (see below)
    S_ISVTX    0001000   sticky bit (see below)
    S_IRWXU    00700     mask for file owner permissions
    S_IRUSR    00400     owner has read permission
    S_IWUSR    00200     owner has write permission
    S_IXUSR    00100     owner has execute permission
    S_IRWXG    00070     mask for group permissions
    S_IRGRP    00040     group has read permission
    S_IWGRP    00020     group has write permission
    S_IXGRP    00010     group has execute permission
    S_IRWXO    00007     mask for permissions for others (not in group)
    S_IROTH    00004     others have read permission
    S_IWOTH    00002     others have write permission
    S_IXOTH    00001     others have execute permission

//使用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>

int main(int argc, char *argv[])
{
	struct stat stat_buf;
	int ret = stat(argv[1], stat_buf);
	if(ret == -1)
	{
	  perror("stat error\n");
	  exit(1);
	}
	if(S_ISREG(stat_buf.st_mode)) //判断是否普通文件
	{
	  printf("Is's a regular\n");
	}else if(S_ISDIR(sbuf.st_mode)){  //判读是否目录
	printf("Is's a dir\n");
	}else if(S_ISCHR(sbuf.st_mode)){  //判断是否字符设备
	printf("Is's a char device\n");
	}else if(S_ISFIFO(sbuf.st_mode)){	//判断是否管道
	printf("Is's a fifo\n");
	}
	return 0;
}

参考文章:struct dirent 和 struct stat 结构体

strftime()

strftime是一种计算机函数,根据区域设置格式化本地时间/日期,函数的功能将时间格式化,或者说格式化一个时间字符串。
我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在str指向的字符串中,最多向str中存放maxsize个字符。该函数返回向str指向的字符串中放置的字符数。

#include <time.h>
size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr)

参数:
str – 这是指向目标数组的指针,用来复制产生的 C 字符串。
maxsize – 这是被复制到 str 的最大字符数。
format – 这是 C 字符串,包含了普通字符和特殊格式说明符的任何组合。这些格式说明符由函数替换为表示 tm 中所指定时间的相对应值。格式说明符是:

	%a 		星期几的简写
	%A 		星期几的全称
	%b 		月份的简写
	%B 		月份的全称
	%c 		标准的日期的时间串
	%C 		年份的前两位数字
	%d 		十进制表示的每月的第几天
	%D 		月/天/年
	%e 		在两字符域中,十进制表示的每月的第几天
	%F		 年-月-日
	%g 		年份的后两位数字,使用基于周的年
	%G 		年份,使用基于周的年
	%h 		简写的月份名
	%H	 	24小时制的小时
	%I 		12小时制的小时
	%j 		十进制表示的每年的第几天
	%m 		十进制表示的月份
	%M 		十时制表示的分钟数
	%n 		新行符
	%p 		本地的AM或PM的等价显示
	%r 		12小时的时间
	%R 		显示小时和分钟:hh:mm
	%S 		十进制的秒数
	%t 		水平制表符
	%T 		显示时分秒:hh:mm:ss
	%u 		每周的第几天,星期一为第一天 (值从1到7,星期一为1)
	%U 		第年的第几周,把星期日作为第一天(值从0到53)
	%V 		每年的第几周,使用基于周的年
	%w 		十进制表示的星期几(值从0到6,星期天为0)
	%W  	 每年的第几周,把星期一做为第一天(值从0到53)
	%x    	标准的日期串
	%X   	 标准的时间串
	%y    	不带世纪的十进制年份(值从0到99)
	%Y   	带世纪部分的十制年份
	%z,	%Z 时区名称,如果不能得到时区名称则返回空字符。
	%%  	 百分号
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ted[11]; // 文件权限 mode_t mode = st.st_mode; limitted[0] = (S_ISDIR(mode)) ? "d" : "-"; limitted[1] = (mode & S_IRUSR) ? "r" : "-"; limitted[2] = (mode & S_IWUSR) ? "w" : "-"; limitted[3] = (mode & S_IXUSR) ? "x" : "-"; limitted[4] = (mode & S_IRGRP) ? "r" : "-"; limitted[5] = (mode & S_IWGRP) ? "w" : "-"; limitted[6] = (mode & S_IXGRP) ? "x" : "-"; limitted[7] = (mode & S_IROTH) ? "r" : "-"; limitted[8] = (mode & S_IWOTH) ? "w" : "-"; limitted[9] = (mode & S_IXOTH) ? "x" : "-"; limitted[10] = '\0'; printf("%s ", limitted); // 链接数、所有者、所在组、文件大小、创建时间、文件名 printf("%ld ", (long)st.st_nlink); printf("%s ", getpwuid(st.st_uid)->pw_name); printf("%s ", getgrgid(st.st_gid)->gr_name); printf("%lld ", (long long)st.st_size); char time_buf[20]; strftime(time_buf, 20, "%b %d %H:%M", localtime(&st.st_ctime)); printf("%s ", time_buf); printf("%s\n", file); } int main(int argc, char *argv[]) { DIR *dir; struct dirent *ptr; struct stat st; char path[256]; if (argc == 1) { getcwd(path, 256); dir = opendir(path); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; stat(ptr->d_name, &st); shell_ls_l(ptr->d_name, st); } } else if (argc == 2) { if (strcmp(argv[1], "-l") == 0) { getcwd(path, 256); dir = opendir(path); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; stat(ptr->d_name, &st); shell_ls_l(ptr->d_name, st); } } else { dir = opendir(argv[1]); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; sprintf(path, "%s/%s", argv[1], ptr->d_name); stat(path, &st); shell_ls_l(ptr->d_name, st); } } } else if (argc == 3) { if (strcmp(argv[1], "-l") == 0) { dir = opendir(argv[2]); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; sprintf(path, "%s/%s", argv[2], ptr->d_name); stat(path, &st); shell_ls_l(ptr->d_name, st); } } } return 0; } 这是一个简单的实现Linux命令ls -l的程序,可以列出文件的权限、链接数、所有者、所在组、文件大小、创建时间、文件名等信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值