C使用stat获取文件名、大小和权限
我正在尝试递归打印目录及其子目录中的所有文件及其大小和权限。这是代码C使用stat获取文件名、大小和权限,c,file,subdirectory,C,File,Subdirectory,我正在尝试递归打印目录及其子目录中的所有文件及其大小和权限。这是代码 #include <unistd.h> #include <sys/types.h> #include <dirent.h> #include <stdio.h> #include <sys/stat.h> void listdir(const char *name, int depth) { DIR *dir; struct dirent *dir_reader;
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
void listdir(const char *name, int depth)
{
DIR *dir;
struct dirent *dir_reader;
if (!(dir = opendir(name)))
return;
if (!(dir_reader = readdir(dir)))
return;
do {
char path[1024];
char absolute_path[1024];
getcwd(absolute_path, 1024);
int size;
if (dir_reader->d_type == DT_DIR) {
int len = snprintf(path, sizeof(path)-1, "%s/%s", name, dir_reader->d_name);
path[len] = 0;
if (strcmp(dir_reader->d_name, ".") == 0 || strcmp(dir_reader->d_name, "..") == 0)
continue;
printf("%*s[%s] %s\n", depth*2, "", dir_reader->d_name,path);
listdir(path, depth + 1);
}
else{
struct stat st;
char* tmp_path = path + 1;
strcat(absolute_path,tmp_path);
if (stat(dir_reader->d_name, &st) == 0){
size = st.st_size;
}
printf("%*s- %s %s %d ", depth*2, "", dir_reader->d_name, absolute_path, size);
printf( (st.st_mode & S_IRUSR) ? "r" : "-");
printf( (st.st_mode & S_IWUSR) ? "w" : "-");
printf( (st.st_mode & S_IXUSR) ? "x" : "-");
printf( (st.st_mode & S_IRGRP) ? "r" : "-");
printf( (st.st_mode & S_IWGRP) ? "w" : "-");
printf( (st.st_mode & S_IXGRP) ? "x" : "-");
printf( (st.st_mode & S_IROTH) ? "r" : "-");
printf( (st.st_mode & S_IWOTH) ? "w" : "-");
printf( (st.st_mode & S_IXOTH) ? "x" : "-");
printf("\n");
}
} while (dir_reader = readdir(dir));
closedir(dir);
}
int main(void) {
listdir(".", 0);
return 0;
}
#包括
#包括
#包括
#包括
#包括
void listdir(常量字符*名称,整数深度)
{
DIR*DIR;
结构目录*目录读取器;
如果(!(dir=opendir(name)))
返回;
如果(!(dir_reader=readdir(dir)))
返回;
做{
字符路径[1024];
字符绝对路径[1024];
getcwd(绝对路径,1024);
整数大小;
if(dir\u reader->d\u type==DT\u dir){
int len=snprintf(路径,sizeof(路径)-1,“%s/%s”,名称,dir\u reader->d\u name);
路径[len]=0;
if(strcmp(dir_reader->d_name,“.”)==0 | | strcmp(dir_reader->d_name,“…”)==0)
继续;
printf(“%*s[%s]%s\n”,深度*2,”,目录读取器->数据单元名称,路径);
listdir(路径,深度+1);
}
否则{
结构统计;
char*tmp_path=path+1;
strcat(绝对路径、tmp路径);
if(stat(dir\u reader->d\u name,&st)==0){
尺寸=标准尺寸;
}
printf(“%*s-%s%s%d”,深度*2,”,dir\u reader->d\u名称,绝对路径,大小);
printf((st.st\U模式和S\U IRUSR)?“r”:“—”;
printf((st.st\U模式和S\U IWUSR)?“w”:“-”);
printf((st.st_模式和S_IXUSR)?“x”:“-”);
printf((st.st\U模式和S\U IRGRP)?“r”:“—”;
printf((st.st\U模式和S\U IWGRP)-“w”:“-”;
printf((st.st_模式和S_IXGRP)?“x”:“-”;
printf((圣圣圣日耳曼模式和圣日耳曼模式)-“r”:“—”;
printf((st.st_模式和S_IWOTH)-“w”:“-”;
printf((st.st_模式和S_IXOTH)?“x”:“-”号;
printf(“\n”);
}
}而(dir_reader=readdir(dir));
closedir(dir);
}
内部主(空){
listdir(“.”,0);
返回0;
}
不幸的是,输出仅为主目录中的文件生成大小和权限,对于子目录中的文件,它仅打印为0作为大小,而----------作为权限。我看不出发生这种情况的原因,IMO递归应该在这里工作,并且打印子目录中的文件,不仅是名称,还有其他信息(特别是每次都打印正确的绝对路径)。之所以大小为0,是因为您没有看到正确的文件。在子目录中,您将“myfile.txt”传递给
stat
而不是“mysubdir/myfile.txt”,因此除非当前目录中碰巧有另一个“myfile.txt”,否则它将无法工作
解决办法很简单。您需要有一个新字符串,将完整路径和文件名连接在一起,并将其传递到文件检查的
部分顶部的stat
char* tmp_path = path + 1;
strcat(absolute_path,tmp_path);
尚未设置路径
变量。因此,您正在读取未初始化的数据,调用未定义的行为。调用stat
时也没有检查错误,因此您不知道它失败了
您需要将path
的设置移动到if
块的外部,以便在这两种情况下都发生。您还需要将absolute\u path
传递到stat
而不是dir\u reader->d\u name
,后者只是文件名
// do this outsize of the if
int len = snprintf(path, sizeof(path)-1, "%s/%s", name, dir_reader->d_name);
path[len] = 0;
if (dir_reader->d_type == DT_DIR) {
if (strcmp(dir_reader->d_name, ".") == 0 || strcmp(dir_reader->d_name, "..") == 0)
continue;
printf("%*s[%s] %s\n", depth*2, "", dir_reader->d_name,path);
listdir(path, depth + 1);
}
else{
struct stat st;
char* tmp_path = path + 1;
strcat(absolute_path,tmp_path);
// use absolute_path to get the file status
if (stat(absolute_path, &st) == 0){
size = st.st_size;
} else {
// error, print message
perror("stat failed");
continue;
}
注意:不需要在snprintf(path,sizeof(path)-1中使用-1…
也不需要path[len]=0;
。根据负值检查len
,或者len>=sizeof(path)
就可以了strcat(绝对路径,tmp_路径);
?如果stat(stat
失败。您以错误的方式管理绝对路径;在递归的每一个深度,您都会使用getcwd(),因为您不更改“当前目录”。可能最好使用与例程第一部分相同的方法-始终使用收到的参数snprintf()并以增量方式构造新的(相对)路径。