#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include"malloc.h"
#define true 1
#define false 0
#define Datatype char
//队列的数据结构,用链表方式实现
typedef struct node{
Datatype data[1024];//结点数据域,用于存放路径
struct node *next;//结点指针域
}QueueNode;//结点的结构体
typedef struct{
QueueNode *front;//队首
QueueNode *rear;//队尾
}LinkQueue,*PQUEUE;//队列的结构体
//初始化队列
void InitQueue(PQUEUE Q)
{
Q->front = Q->rear = NULL;
}
//判断队列是否为空
int QueueEmpty(PQUEUE Q)
{
return(Q->front == NULL && Q->rear == NULL);
}
//入队
void EnLinkQueue(PQUEUE Q, Datatype *v)
{
QueueNode *p;
p = (QueueNode *)malloc(sizeof(QueueNode));
strcpy(p->data , v);
p->next = NULL;
if(QueueEmpty(Q)) Q->front = Q->rear = p;
else
{
Q->rear->next = p;
Q->rear = p;
}
}
//出队
void DeLinkQueue(PQUEUE Q,Datatype *i)
{
QueueNode *s;
if(QueueEmpty(Q)) { //如果队列为空,报错
printf("Error,the linkqueue is empty!");
return;
}
s = Q->front;
strcpy(i , s->data);
if(Q->front == Q->rear)
Q->front = Q->rear = NULL;
else
Q->front = s->next;
free(s);
}
static int get_file_size_time(const char *filename)
{
struct stat statbuf;
if(stat(filename,&statbuf) == -1)
{
printf("Get start on %s Error:%s\n",filename,strerror(errno));
return(-1);
}
if(S_ISDIR(statbuf.st_mode))
{
return(1);//判断是否是目录
}
if(S_ISREG(statbuf.st_mode))
printf("%s size:%ld bytes\tmodified at %s",filename,statbuf.st_size,ctime(&statbuf.st_mtime));
return(0);//若是普通文件,则处处文件路径,大小和修改时间
}
int cursive(PQUEUE Q,char *argv)//遍历队列中的目录
{
DIR *dirp;
struct dirent *direntp;
int stats,stat;
char path1[1024];
char pathtmp[1024];
if(((stats = get_file_size_time(argv))==0)||(stats==-1))
exit(1);
if((dirp=opendir(argv))==NULL)
{
printf("Open Directory %s Error:%s\n",argv,strerror(errno));
exit(1);
}
while((direntp = readdir(dirp))!=NULL)
{
strcpy(path1,argv);
strcat(path1,"/");
strcat(path1,direntp->d_name);
stat=get_file_size_time(path1);
if(stat==-1)
break;
if(stat==1&&path1[strlen(path1)-1]!='.'){
EnLinkQueue(Q,path1);
}//如果是子目录文件,则将该路径加入队列
}//遍历完当前层的普通文件
//开始取出下一层的路径,准备遍历下一层
if(QueueEmpty(Q) == 0)
{//如果队列不空,则从中取出路径
char fullpath[1024];
memset(fullpath,0,1024);
DeLinkQueue(Q,pathtmp);
strcpy(fullpath,pathtmp);
cursive(Q,fullpath);//遍历目录中的文件
}
closedir(dirp);
return 0;
}
int main(int argc,char **argv)
{//逻辑似cursive()函数
DIR *dirp;
struct dirent *direntp;
int stats;
char path[1024];
char pathtmp[1024];
LinkQueue qst;
PQUEUE Q=&qst;
InitQueue(Q);//初始化队列
int stat;
if(argc!=2)
{
printf("Usage:%s filename\n\a",argv[0]);
exit(1);
}
if(((stats = get_file_size_time(argv[1]))==0)||(stats==-1))
exit(1);
if((dirp=opendir(argv[1]))==NULL)
{
printf("Open Directory %s Error:%s\n",argv[1],strerror(errno));
exit(1);
}
while((direntp = readdir(dirp))!=NULL)
{
memset(path,0,1024);
strcpy(path,argv[1]);
strcat(path,"/");
strcat(path,direntp->d_name);
stat=get_file_size_time(path);
if(stat==-1)
break;
if(stat==1&&path[strlen(path)-1]!='.')
EnLinkQueue(Q,path);
}
if(!QueueEmpty(Q))
{
char fullpath[1024];
memset(fullpath,0,1024);
DeLinkQueue(Q,pathtmp);
strcpy(fullpath,pathtmp);
cursive(Q,fullpath);
}
closedir(dirp);
exit(1);
}
本文介绍了如何实现对Linux文件系统的广度优先遍历,以层次结构输出文件信息。通过定义队列数据结构并结合系统调用,程序能够遍历指定目录及其子目录,显示文件的大小和修改时间。
1583

被折叠的 条评论
为什么被折叠?



