网站建设赶集网,怎么才能自己创一个平台,设备外观设计效果图,软件开发专业就业实例要求#xff1a;使用文件IO的接口在一个目录下#xff0c;实现Linux命令“ls -l”的功能#xff1b;实例分析#xff1a;正常使用“ls -l”命令#xff0c;会出现以下内容#xff1a;
/*- rwxrw-rw- 1 linux linux…实例要求使用文件IO的接口在一个目录下实现Linux命令“ls -l”的功能实例分析正常使用“ls -l”命令会出现以下内容
/*- rwxrw-rw- 1 linux linux 26 10月2 14:31 x.txt
文件类型 所属用户的权限\所属组的权限\其他人的权限 硬链接个数 所属用户 所属组 大小字节 时间戳 文件名
*/相关的文件IO接口函数如下opendir函数 #include sys/types.h#include dirent.hDIR *opendir(const char *name);/*功能打开一个目录文件参数name目录名返回值成功: 目录指针失败: NULL 重置错误码*/
readdir函数 #include dirent.hstruct dirent *readdir(DIR *dirp);/*功能读取目录下的内容参数目录指针返回值成功 dirent结构体指针失败 NULL 重置错误码*/// dirent结构体指针struct dirent {ino_t d_ino; /* 读到的文件的inode号 */off_t d_off; /* 无需关注 */unsigned short d_reclen; /* 这个结构体的大小 不是文件的大小 */unsigned char d_type; /* 文件类型 */DT_BLK This is a block device.DT_CHR This is a character device.DT_DIR This is a directory.DT_FIFO This is a named pipe (FIFO).DT_LNK This is a symbolic link.DT_REG This is a regular file.DT_SOCK This is a UNIX domain socket.char d_name[256]; /* 文件名 */};
closedir函数 #include sys/types.h#include dirent.hint closedir(DIR *dirp);/*功能关闭一个目录参数dirp目录指针返回值成功: 0失败: -1 重置错误码*/
stat函数 #include sys/types.h#include sys/stat.h#include unistd.hint stat(const char *pathname, struct stat *statbuf);/*功能获取文件的属性信息参数pathname文件的路径和名字statbuf用来保存文件属性的结构体返回值成功 0失败 -1 重置错误码*///文件属性的结构体struct stat {dev_t st_dev; /* 文件所在磁盘的设备号 */ino_t st_ino; /* inode号 */mode_t st_mode; /* 文件的类型和访问模式 *///S_IFMT 0170000 文件类型的掩码//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 if((S_IFMT st_mode) S_IFREG){//注意优先级问题printf(普通文件\n);}//或者用下面的宏判断if(S_ISREG(m)){printf(普通文件\n);}//st_mode 0777 文件的权限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; /* 块的大小 */blkcnt_t st_blocks; /* 块的数量 */struct timespec st_atim; /* 最后一次访问的时间 */struct timespec st_mtim; /* 最后一次修改的时间 */struct timespec st_ctim; /* 最后一次状态改变的时间 *///下面的宏定义是为了方便获取时间戳里的秒数的#define st_atime st_atim.tv_sec /* Backward compatibility */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec};getpwuid函数 #include sys/types.h#include pwd.hstruct passwd *getpwuid(uid_t uid);/*功能根据uid获取用户信息参数uid: 用户id返回值成功: 用户信息结构体失败: NULL 重置错误码*///用户信息结构体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 */};
getgrgid函数 #include sys/types.h#include grp.hstruct group *getgrgid(gid_t gid);/*功能根据gid获取组信息参数gid: 组id返回值成功 组信息结构体失败 NULL 重置错误码*/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 pointers to names of group members */};
sprintf函数 #include stdio.hint sprintf(char *str, const char *format, ...);/*功能将格式化的信息写入str指向的缓冲区中参数str 自定义的缓冲区的首地址format 格式... 可变参返回值成功 格式化的字符的个数失败 小于0的值*/示例代码
#include stdio.h
#include stdlib.h
#include string.h
#include sys/types.h
#include dirent.h
#include sys/stat.h
#include unistd.h
#include pwd.h
#include grp.h
#include time.h//所属用户权限宏定义
#define U_R 0400
#define U_W 0200
#define U_X 0100//所属组权限宏定义
#define G_R 0040
#define G_W 0020
#define G_X 0010//其他人权限宏定义
#define O_R 0004
#define O_W 0002
#define O_X 0001int main(int argc, const char *argv[])
{//入参合理性检查if (2 ! argc){printf(Usage : %s dir_name\n, argv[0]);return -1;}// 打开目录DIR *my_dir opendir(argv[1]);if (NULL my_dir){perror(opendir error);return -1;}//文件的类型char type -;//所属用户权限赋初值char u_r -;char u_w -;char u_x -;//所属组权限赋初值char g_r -;char g_w -;char g_x -;//其他人权限赋初值char o_r -;char o_w -;char o_x -;int nlink 0;char u_name[64] {0};char g_name[64] {0};int size 0;char date[128] {0};char path_name[512] {0};struct tm *p NULL;struct stat lk;struct dirent *dir NULL;int mode 0;while (NULL ! (dir readdir(my_dir))){ //过滤隐藏文件if (. *(dir-d_name)){continue;}//文件类型switch (dir-d_type){case DT_BLK:type b;break;case DT_SOCK:type s;break;case DT_FIFO:type p;break;case DT_REG:type -;break;case DT_LNK:type l;break;case DT_CHR:type c;break;case DT_DIR:type d;break;}//数组清零memset(path_name, 0, sizeof(path_name));//组装路径sprintf(path_name, %s/%s, argv[1], dir-d_name);if (stat(path_name, lk)){perror(stat error);return -1;}u_r -;u_w -;u_x -;g_r -;g_w -;g_x -;o_r -;o_w -;o_x -;// 文件权限mode lk.st_mode 0777;if (mode U_R){u_r r;}if (mode U_W){u_w w;}if (mode U_X){u_x x;}if (mode G_R){g_r r;}if (mode G_W){g_w w;}if (mode G_X){g_x x;}if (mode O_R){o_r r;}if (mode O_W){o_w w;}if (mode O_X){o_x x;}//硬链接的个数nlink lk.st_nlink;//所属用户名strcpy(u_name, getpwuid(lk.st_uid)-pw_name);//所属组名strcpy(g_name, getgrgid(lk.st_gid)-gr_name);//文件的大小字节size lk.st_size;//时间戳(最后一次修改的时间)p localtime((lk.st_mtime));sprintf(date, %2d月%2d %02d:%02d, p-tm_mon 1, \p-tm_mday, p-tm_hour, p-tm_min);//输出文件的基本内容printf(%c%c%c%c%c%c%c%c%c%c %d %s %s %7d %s %-s\n,\type, u_r, u_w, u_x, g_r, g_w, g_x, o_r, o_w, o_x, nlink,\u_name, g_name, size, date, dir-d_name);}// 关闭目录closedir(my_dir);return 0;
}运行结果
linuxubuntu:~$ ./a.out ./
-rw-rw-r-- 1 linux linux 730 10月 1 22:44 k1.c
-rw-rw-r-- 1 linux linux 26 10月 1 22:40 k2.txt
-rwxrwxr-x 1 linux linux 12984 10月 2 19:31 a.out
-rw-rw-r-- 1 linux linux 4078 10月 2 19:17 ls-l.c
drwxrwxr-x 2 linux linux 4096 10月 2 18:59 k3
linuxubuntu:~$ ls -l
总用量 32
-rwxrwxr-x 1 linux linux 12984 10月 2 19:31 a.out
-rw-rw-r-- 1 linux linux 730 10月 1 22:44 k1.c
-rw-rw-r-- 1 linux linux 26 10月 1 22:40 k2.txt
drwxrwxr-x 2 linux linux 4096 10月 2 18:59 k3
-rw-rw-r-- 1 linux linux 4078 10月 2 19:17 ls-l.c本示例代码仅供参考