- 姓名:黄碧婷
- 学号:201821121032
- 班级:计算1812
1. 编写程序
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<dirent.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>
void error_printf(const char* );
void list_dir(const char* );
void list_message(const char* , const struct stat*);
void file_type(const struct stat* );
void file_power(const struct stat* );
void file_id(const struct stat* );
void file_mtime(const struct stat* );
void link_printf(const char* );
void error_printf(const char* funname)
{
perror(funname);
exit(EXIT_FAILURE);
/*
* EXIT_SUCCESS和EXIT_FAILURE是两个常量。
* EXIT_SUCCESS=0,EXIT_FAILURE=1。
* 0表示程序寿终正寝,1表示死于非命。
*/
}
void list_dir(const char* pathname)
{
DIR* ret_opendir = opendir(pathname); // 打开目录"pathname"
if(ret_opendir == NULL)
error_printf("opendir");
int ret_chdir = chdir(pathname); // 改变工作目录至"pathname",便于stat函数的使用
if(ret_chdir == -1)
error_printf("chdir");
struct dirent* ret_readdir = NULL; // 定义readdir函数返回的结构体变量
while(ret_readdir = readdir(ret_opendir)) // 判断是否读取到目录尾
{
char* filename = ret_readdir->d_name; // 获取文件名
struct stat file_message = {}; // 定义stat函数返回的结构体变量
int ret_stat = lstat(filename, &file_message); // 获取文件信息
if(ret_stat == -1) // stat读取文件错误则输出提示信息
printf("%s error!", filename);
else if(strcmp(filename,".") && strcmp(filename,"..")) // 不输出当前目录与上一级目录
list_message(filename, &file_message);
}
}
void list_message(const char* filename, const struct stat* file_message)
{
file_type(file_message); // 判断打印文件类型
printf("%d ",(int)file_message->st_ino);//添加索引号
file_power(file_message); // 判断并打印文件权限
printf("%d ", file_message->st_nlink); // 打印硬链接数
file_id(file_message); // 转换并打印用户id与组id
printf("%5ld ", file_message->st_size); // 打印文件大小
file_mtime(file_message); // 打印文件最后修改时间
printf("%s ", filename); // 打印文件名
if(S_ISLNK(file_message->st_mode)) // 如果是软链接文件,打印其指向的位置
link_printf(filename);
puts("");
}
void file_type(const struct stat* file_message)
{
mode_t mode = file_message->st_mode;
if (S_ISREG(mode)) printf("-"); // 普通文件
else if(S_ISDIR(mode)) printf("d"); // 目录文件
else if(S_ISCHR(mode)) printf("c"); // 字符设备文件
else if(S_ISBLK(mode)) printf("b"); // 块设备文件
else if(S_ISFIFO(mode)) printf("p"); // 管道文件
else if(S_ISLNK(mode)) printf("l"); // 链接文件
else printf("s"); // socket文件
}
void file_power(const struct stat* file_message)
{
mode_t mode = file_message->st_mode;
printf("%c", mode&S_IRUSR?'r':'-');
printf("%c", mode&S_IWUSR?'w':'-');
printf("%c", mode&S_IXUSR?'x':'-');
printf("%c", mode&S_IRGRP?'r':'-');
printf("%c", mode&S_IWGRP?'w':'-');
printf("%c", mode&S_IXGRP?'x':'-');
printf("%c", mode&S_IROTH?'r':'-');
printf("%c", mode&S_IWOTH?'w':'-');
printf("%c ", mode&S_IXOTH?'x':'-');
}
void file_id(const struct stat* file_message)
{
struct passwd* pwd;
pwd = getpwuid(file_message->st_uid);
printf("%s ",pwd->pw_name);
struct group* grp;
grp = getgrgid(file_message->st_gid);
printf("%s ",grp->gr_name);
}
void file_mtime(const struct stat* file_message)
{
struct tm* t = localtime(&file_message->st_mtime);
printf("%2d月 %2d %02d:%02d ", t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min);
}
void link_printf(const char* filename)
{
char buf[1024] = "123";
if(0 == readlink(filename, buf, sizeof(buf)))
error_printf("readlink");
printf("-> %s ",buf);
}
int main()
{ char path[1024] = {};
strcpy(path,"./");
struct stat file_message = {};
int ret_stat = lstat(path, &file_message);
if(ret_stat == -1)
error_printf("stat");
if(S_ISDIR(file_message.st_mode)) // 判断是否为目录
list_dir(path);
else
list_message(path, &file_message);
return 0;
}
2. 分析运行结果
本题的思路在实验报告中有提到:
获取当前工作目录路径 打开目录 读取目录文件 ;
对每一个文件,读取文件属性,解释文件属性,格式化输出。
运行结果截图:
执行 ls -lai:
执行结果分析:
这次实验显示的内容有八个属性,对应下列的运行结果:
923838 -rwxr-xr-x 1 huangbiting jmu-cs-18 13368 Apr 30 20:21 -
920475 drwxr--r-x 4 huangbiting jmu-cs-18 4096 Apr 30 20:29 .
131195 drwxr-xr-x 129 root root 4096 Apr 25 21:52 ..
923849 -rw-r--r-- 1 huangbiting jmu-cs-18 39 Apr 30 20:04 1
922203 -rw------- 1 huangbiting jmu-cs-18 3678 Apr 30 20:29 .bash_history
920476 -rw-r--r-- 1 huangbiting jmu-cs-18 220 Apr 5 2018 .bash_logout
920478 -rw-r--r-- 1 huangbiting jmu-cs-18 3771 Apr 5 2018 .bashrc
922092 drwx------ 2 huangbiting jmu-cs-18 4096 Mar 18 08:34 .cache
1. 判断打印文件类型
file_type(file_message);
2. 文件索引节点号(inode)
printf("%d ",(int)file_message->st_ino);
3.判断文件权限
void file_power(const struct stat* file_message)
{
mode_t mode = file_message->st_mode;
printf("%c", mode&S_IRUSR?'r':'-');
printf("%c", mode&S_IWUSR?'w':'-');
printf("%c", mode&S_IXUSR?'x':'-');
printf("%c", mode&S_IRGRP?'r':'-');
printf("%c", mode&S_IWGRP?'w':'-');
printf("%c", mode&S_IXGRP?'x':'-');
printf("%c", mode&S_IROTH?'r':'-');
printf("%c", mode&S_IWOTH?'w':'-');
printf("%c ", mode&S_IXOTH?'x':'-');
}
4. 硬链接数
printf("%d ", file_message->st_nlink);
5. 打印文件大小
printf("%5ld ", file_message->st_size);
6.转换并打印用户id与组id
file_id(file_message);
7.打印文件最后修改时间
file_mtime(file_message);
8. 打印文件名
printf("%s ", filename);
3. 通过该实验产生新的疑问及解答
疑问:运行结果中显示的 Total 216 的含义是什么?
答:列表中所有文件的磁盘空间占用总和,也就是资源占用总和,它的统计单位是kb。
referrence: https://www.cnblogs.com/usingnamespace-caoliu/p/9351773.html
https://blog.csdn.net/apollon_krj/article/details/54710135
- 姓名:黄碧婷
- 学号:201821121032
- 班级:计算1812
1. 编写程序
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<dirent.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>
void error_printf(const char* );
void list_dir(const char* );
void list_message(const char* , const struct stat*);
void file_type(const struct stat* );
void file_power(const struct stat* );
void file_id(const struct stat* );
void file_mtime(const struct stat* );
void link_printf(const char* );
void error_printf(const char* funname)
{
perror(funname);
exit(EXIT_FAILURE);
/*
* EXIT_SUCCESS和EXIT_FAILURE是两个常量。
* EXIT_SUCCESS=0,EXIT_FAILURE=1。
* 0表示程序寿终正寝,1表示死于非命。
*/
}
void list_dir(const char* pathname)
{
DIR* ret_opendir = opendir(pathname); // 打开目录"pathname"
if(ret_opendir == NULL)
error_printf("opendir");
int ret_chdir = chdir(pathname); // 改变工作目录至"pathname",便于stat函数的使用
if(ret_chdir == -1)
error_printf("chdir");
struct dirent* ret_readdir = NULL; // 定义readdir函数返回的结构体变量
while(ret_readdir = readdir(ret_opendir)) // 判断是否读取到目录尾
{
char* filename = ret_readdir->d_name; // 获取文件名
struct stat file_message = {}; // 定义stat函数返回的结构体变量
int ret_stat = lstat(filename, &file_message); // 获取文件信息
if(ret_stat == -1) // stat读取文件错误则输出提示信息
printf("%s error!", filename);
else if(strcmp(filename,".") && strcmp(filename,"..")) // 不输出当前目录与上一级目录
list_message(filename, &file_message);
}
}
void list_message(const char* filename, const struct stat* file_message)
{
file_type(file_message); // 判断打印文件类型
printf("%d ",(int)file_message->st_ino);//添加索引号
file_power(file_message); // 判断并打印文件权限
printf("%d ", file_message->st_nlink); // 打印硬链接数
file_id(file_message); // 转换并打印用户id与组id
printf("%5ld ", file_message->st_size); // 打印文件大小
file_mtime(file_message); // 打印文件最后修改时间
printf("%s ", filename); // 打印文件名
if(S_ISLNK(file_message->st_mode)) // 如果是软链接文件,打印其指向的位置
link_printf(filename);
puts("");
}
void file_type(const struct stat* file_message)
{
mode_t mode = file_message->st_mode;
if (S_ISREG(mode)) printf("-"); // 普通文件
else if(S_ISDIR(mode)) printf("d"); // 目录文件
else if(S_ISCHR(mode)) printf("c"); // 字符设备文件
else if(S_ISBLK(mode)) printf("b"); // 块设备文件
else if(S_ISFIFO(mode)) printf("p"); // 管道文件
else if(S_ISLNK(mode)) printf("l"); // 链接文件
else printf("s"); // socket文件
}
void file_power(const struct stat* file_message)
{
mode_t mode = file_message->st_mode;
printf("%c", mode&S_IRUSR?'r':'-');
printf("%c", mode&S_IWUSR?'w':'-');
printf("%c", mode&S_IXUSR?'x':'-');
printf("%c", mode&S_IRGRP?'r':'-');
printf("%c", mode&S_IWGRP?'w':'-');
printf("%c", mode&S_IXGRP?'x':'-');
printf("%c", mode&S_IROTH?'r':'-');
printf("%c", mode&S_IWOTH?'w':'-');
printf("%c ", mode&S_IXOTH?'x':'-');
}
void file_id(const struct stat* file_message)
{
struct passwd* pwd;
pwd = getpwuid(file_message->st_uid);
printf("%s ",pwd->pw_name);
struct group* grp;
grp = getgrgid(file_message->st_gid);
printf("%s ",grp->gr_name);
}
void file_mtime(const struct stat* file_message)
{
struct tm* t = localtime(&file_message->st_mtime);
printf("%2d月 %2d %02d:%02d ", t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min);
}
void link_printf(const char* filename)
{
char buf[1024] = "123";
if(0 == readlink(filename, buf, sizeof(buf)))
error_printf("readlink");
printf("-> %s ",buf);
}
int main()
{ char path[1024] = {};
strcpy(path,"./");
struct stat file_message = {};
int ret_stat = lstat(path, &file_message);
if(ret_stat == -1)
error_printf("stat");
if(S_ISDIR(file_message.st_mode)) // 判断是否为目录
list_dir(path);
else
list_message(path, &file_message);
return 0;
}
2. 分析运行结果
本题的思路在实验报告中有提到:
获取当前工作目录路径 打开目录 读取目录文件 ;
对每一个文件,读取文件属性,解释文件属性,格式化输出。
运行结果截图:
执行 ls -lai:
执行结果分析:
这次实验显示的内容有八个属性,对应下列的运行结果:
923838 -rwxr-xr-x 1 huangbiting jmu-cs-18 13368 Apr 30 20:21 -
920475 drwxr--r-x 4 huangbiting jmu-cs-18 4096 Apr 30 20:29 .
131195 drwxr-xr-x 129 root root 4096 Apr 25 21:52 ..
923849 -rw-r--r-- 1 huangbiting jmu-cs-18 39 Apr 30 20:04 1
922203 -rw------- 1 huangbiting jmu-cs-18 3678 Apr 30 20:29 .bash_history
920476 -rw-r--r-- 1 huangbiting jmu-cs-18 220 Apr 5 2018 .bash_logout
920478 -rw-r--r-- 1 huangbiting jmu-cs-18 3771 Apr 5 2018 .bashrc
922092 drwx------ 2 huangbiting jmu-cs-18 4096 Mar 18 08:34 .cache
1. 判断打印文件类型
file_type(file_message);
2. 文件索引节点号(inode)
printf("%d ",(int)file_message->st_ino);
3.判断文件权限
void file_power(const struct stat* file_message)
{
mode_t mode = file_message->st_mode;
printf("%c", mode&S_IRUSR?'r':'-');
printf("%c", mode&S_IWUSR?'w':'-');
printf("%c", mode&S_IXUSR?'x':'-');
printf("%c", mode&S_IRGRP?'r':'-');
printf("%c", mode&S_IWGRP?'w':'-');
printf("%c", mode&S_IXGRP?'x':'-');
printf("%c", mode&S_IROTH?'r':'-');
printf("%c", mode&S_IWOTH?'w':'-');
printf("%c ", mode&S_IXOTH?'x':'-');
}
4. 硬链接数
printf("%d ", file_message->st_nlink);
5. 打印文件大小
printf("%5ld ", file_message->st_size);
6.转换并打印用户id与组id
file_id(file_message);
7.打印文件最后修改时间
file_mtime(file_message);
8. 打印文件名
printf("%s ", filename);
3. 通过该实验产生新的疑问及解答
疑问:运行结果中显示的 Total 216 的含义是什么?
答:列表中所有文件的磁盘空间占用总和,也就是资源占用总和,它的统计单位是kb。
referrence: https://www.cnblogs.com/usingnamespace-caoliu/p/9351773.html
https://blog.csdn.net/apollon_krj/article/details/54710135