给出指定目录文件系统的目录结构,以凹入法写入文件dir_structure.txt文档中,并计算出该目录所占存储区域大小。(凹入法显示参见P93)
本人提供Linux和WindowsC++编译环境下的两个版本的代码,分别可以在Dev-C++和VS2019上取得编译通过!
实现效果:
Dev-C++代码:
#include<stdio.h>
#include<cstring>
#include<unistd.h>
#include<dirent.h>//目录操作的头文件
#include<sys/stat.h>
#include<stdlib.h>
FILE*fp;
//测试模块
long long Size=0l;
void printdir(char *dir, int depth)
{
DIR *pdir = opendir(dir);//返回一个目录流
if(NULL == pdir)
{
fprintf(stderr,"cannot open directory:%s\n",dir);
return;//stderr直接输出,不经缓冲区
}
chdir(dir);//用于改变当前工作目录,其参数为Path 目标目录
struct dirent *pentry;
struct stat statbuf;
while((pentry = readdir(pdir)) != NULL)
{
stat(pentry->d_name,&statbuf);
if(S_ISDIR(statbuf.st_mode)){
if(strcmp(".",pentry->d_name) == 0 || strcmp("..",pentry->d_name) == 0){
continue;
}
printf("%*s%s/\n",depth,"",pentry->d_name);
fprintf(fp,"%*s%s/\n",depth,"",pentry->d_name);
printdir(pentry->d_name,depth+4);
}
else{
// printf("%d",depth);
Size+=statbuf.st_size;
printf("%*s%s\n",depth,"",pentry->d_name);
fprintf(fp,"%*s%s\n",depth,"",pentry->d_name);
}
}
chdir("..");//返回上一级目录
closedir(pdir);//关闭参数dir所指的目录流。关闭成功则返回0,失败返回-1
}
int main(){
char topdir[]="D:\\Program Files (x86)\\TTKN\\CAJViewer 7.2";
fp=fopen("C:\\Users\\wyx03\\Desktop\\dir_structure.txt","w");
printf("The directory is %s: \n",topdir);
printdir(topdir,0);
fclose(fp);
printf("Done!\n");
printf("The total size :%lld bytes",Size);
return 0;
}
VS2019版本实现效果:
VS2019实现代码:
#include<iostream>
#include<string>
#include<io.h>
#include<cstdlib>
#include<cstring>
using namespace std;
FILE* fp;
long long Size=0;//预先设定大小变量
void TransFile(char * Fname, int depth) {
fprintf(fp, "%*s%s/\n", depth, "", Fname);
}
void fileSearch(string path, int depth)
{
long fHandle = 0;//_findfirst函数返回回来的句柄。
/*
_finddata_t 存储文件各种信息的结构体,<io.h>;
*/
struct _finddata_t fa;
string pathName;
pathName = path;
/*
\\* 表示符合的所有文件;没有找到即文件夹为空,退出;
assign 表示把 pathName清空并置为path;append 表示在末尾加上字符串;
c_str 返回一个const char* 的临时指针;
_findfirst
搜索与指定的文件名称匹配的第一个实例,若成功则返回第一个实例的句柄,否则返回-1L;
函数原型:long _findfirst( char *filespec, struct _finddata_t *fa );*/
if ((fHandle = _findfirst((pathName+"\\*").c_str(), &fa)) == -1)
return;
do {
if (strcmp(".", fa.name) == 0 || strcmp("..", fa.name) == 0) {
continue;//直接在while开始读取下一文件。跳过.和..
}
printf("%*s/", depth, "");
string a;a = path + "\\" + fa.name;
Size+= fa.size;
TransFile(fa.name, depth);
//fprintf(fp, "%*s%s/\n", depth, "", fa.name);
//cout << path+"\\"+fa.name << endl;
cout << fa.name << endl;
/*文件夹下有 . 和 .. 目录,不能进入搜索;
_A_SUBDIR 表示文件夹属性;*/
if (strcmp(fa.name, "..") && strcmp(fa.name, ".") && fa.attrib == _A_SUBDIR)
fileSearch(path + "\\" + fa.name, depth + 4);
} while (_findnext(fHandle, &fa) == 0);
/*
_findnext 搜索与_findfirst函数提供的文件名称匹配的下一个实例,若成功则返回0,否则返回-1 ;
_findclose 结束查找;
*/
_findclose(fHandle);
return;
}
int main()
{
fopen_s(&fp,"C:\\Users\\wyx03\\Desktop\\dir_structure.txt", "w");
string path = "C:\\Program Files (x86)\\Microsoft SDKs\\ClickOnce Bootstrapper";
fileSearch(path, 0);
fclose(fp);
cout << "The Size of " + path + " :" << Size << " bytes " << endl;
printf("Done!\n");
return 0;
}
当然,大家如果希望可以在Dev-C++上运行VS2019的代码,可以试试下面的代码:
#include<iostream>
#include<string>
#include<io.h>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<fstream>
using namespace std;
FILE* fp;
long long Size=0;
void fileSearch(string path, int depth)
{
long hFile = 0;
/*
_finddata_t 存储文件各种信息的结构体,<io.h>;
*/
struct _finddata_t fileInfo;
string pathName;
/*
\\* 表示符合的所有文件;没有找到即文件夹为空,退出;
assign 表示把 pathName清空并置为path;append 表示在末尾加上字符串;
c_str 返回一个const char* 的临时指针;
_findfirst
搜索与指定的文件名称匹配的第一个实例,若成功则返回第一个实例的句柄,否则返回-1L;
函数原型:long _findfirst( char *filespec, struct _finddata_t *fileinfo );*/
if ((hFile = _findfirst(pathName.assign(path).append("\\*").c_str(), &fileInfo)) == -1)
return;
do {
if (strcmp(".", fileInfo.name) == 0 || strcmp("..", fileInfo.name) == 0) {
continue;//直接在while开始读取下一文件。跳过.和..
}
printf("%d%*s/", depth, depth, "");
string a;
a = path + "\\" + fileInfo.name;
Size+= fileInfo.size;
fprintf(fp, "%*s%s/\n", depth, "", a.c_str());
//cout << path+"\\"+fileInfo.name << endl;
cout << fileInfo.name << endl;
/*文件夹下有 . 和 .. 目录,不能进入搜索;
_A_SUBDIR 表示文件夹属性;*/
if (strcmp(fileInfo.name, "..") && strcmp(fileInfo.name, ".") && fileInfo.attrib == _A_SUBDIR)
fileSearch(path + "\\" + fileInfo.name, depth + 4);
} while (_findnext(hFile, &fileInfo) == 0);
/*
_findnext 搜索与_findfirst函数提供的文件名称匹配的下一个实例,若成功则返回0,否则返回-1 ;
_findclose 结束查找;
*/
_findclose(hFile);
return;
}
int main()
{
fp=fopen("C:\\Users\\wyx03\\Desktop\\dir_structure.txt", "w");
string path = "C:\\Program Files (x86)\\Microsoft SDKs\\ClickOnce Bootstrapper";
fileSearch(path, 0);
fclose(fp);
cout << "The Size of "+path+" :"<<Size << endl;
printf("Done!\n");
return 0;
}