C/C++获取Windows的文件占用大小

2 篇文章 0 订阅

C/C++获取Windows的文件占用大小

为了在 C++ 中递归计算文件夹的大小,使用 Windows API 中的 FindFirstFile 和 FindNextFile 函数。

#include <iostream>
#include <windows.h>
#include <string>
#include <locale>

/*
    文件信息
*/
class file_instance{
    public:
        std::wstring* name;
        std::wstring* path;
        int type;
        uintmax_t size;
        file_instance* child;
        file_instance* next;
        file_instance* top;
        std::wstring* get_path()
        {
            return this->path;
        };
        // 获取指定位置的下级文件信息
        file_instance* getPointToFileInstance(int num)
        {
            file_instance* begin = this->child;
            for(int i = 1;NULL!=begin;)
            {
                std::wstring nameContent = *(begin->name);
                if(nameContent == L"." || nameContent==L"..")
                {
                    begin = begin->next;
                    continue;
                }
                if(i==num&&NULL!=begin)
                {
                    return begin;
                }else if(NULL==begin){
                    std::wcout << L"查无对象" <<std::endl;
                    break;
                }
                begin = begin->next;
                i++;
            }
            return NULL;
        };
        // 打印文件内容
        void Print(){
            std::wcout << L"当前所处的目录是:" << *(this->path) << L"\t"
            << L"文件夹名称:"<< *(this->name) << std::endl;
            if(this->child==NULL)
            {
                std::wcout << L"current dir is empty!"<< std::endl;
            }
            else
            {
                file_instance* begin = this->child;
                std::wcout << L"位置\t类型\t文件大小(MB)\t名称"<< std::endl;
                int i = 1 ;
                while(begin!=nullptr)
                {
                    uintmax_t sizeNum = begin->size;
                    std::wstring nameContent = *(begin->name);
                    std::wstring typeContent;
                    if(nameContent == L"." || nameContent==L"..")
                    {
                        begin = begin->next;
                        continue;
                    }
                    if((begin->type)==1)
                    {
                        typeContent.append(L"DIR");
                    }else{
                        typeContent.append(L"FILE");

                    }
                    std::wcout<<i<<L"\t"<<typeContent<<L"\t"<< (sizeNum/1024/1024) <<L"\t" << nameContent <<std::endl;
                    begin = begin->next;
                    i++;
                };
            }
        }

};

/*
    递归遍历文件
*/
file_instance* get_folder_size(file_instance* parent) {

    WIN32_FIND_DATAW find_data;
    int fileLen = 0;
    file_instance* start = NULL;
    file_instance* next = NULL;
    std::wstring* currentPath = new std::wstring(parent->path->c_str());
    HANDLE find_handle = FindFirstFileW((*(parent->path) + L"\\*").c_str(), &find_data);
    if (find_handle != INVALID_HANDLE_VALUE) {
        do {
            file_instance* childDirector = new file_instance();
            childDirector->name = new std::wstring(find_data.cFileName);
            std::wstring* childDirectorPath = &(new std::wstring(*currentPath))->append(L"\\").append(find_data.cFileName);
            childDirector->path = childDirectorPath;

            childDirector->top = parent;
            // 文件夹
            if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (wcscmp(find_data.cFileName, L".") != 0 && wcscmp(find_data.cFileName, L"..") != 0) {
                   childDirector->type = 1;
                   get_folder_size(childDirector);
                }
            }
            // 普通文件
            else
            {
                childDirector->type = 2;
                childDirector->size += find_data.nFileSizeLow;
                childDirector->size += find_data.nFileSizeHigh * (static_cast<uintmax_t>(MAXDWORD) + 1);
            }

            parent->size += childDirector->size;

            //
            if(next==nullptr)
            {
                start = childDirector;
                next = childDirector;
            }else{
                next->next = childDirector;
                next = next->next;
            }
        } while (FindNextFileW(find_handle, &find_data));
        FindClose(find_handle);
    }
    parent->child = start;
    return parent;
}

// 字符串数字转换为数值
int getNumber(std::string numberString)
{
    setlocale( LC_ALL, "chs" );
    int number = -1;
    try {
        number = std::stoi(numberString);
    } catch (std::invalid_argument& e) {
    } catch (std::out_of_range& e) {
    }
    return number;
}

int main() {

    // ***************************初始化********************************
    // 解决wstring打印不显示的问题
    std::wcout.imbue(std::locale("chs"));
    // 解决中文乱码问题
    system("chcp 65001");

    // ***************************扫描文件信息****************************
    // 创建文件根节点
    file_instance* root = new file_instance();
    std::wstring* name = new std::wstring();
    root->name = name;
    root->path = new std::wstring(L"");
    root->type = 1;
    std::wcout << L"请输入扫描路径:"<< std::endl;
    std::getline(std::wcin,*(root->path));
    std::wcout <<L"正在扫描" << root->path->c_str()<< L"..." << std::endl;
    // 递归扫描获取文件信息
    root = get_folder_size(root);
    std::wcout <<L"扫描完成!" << std::endl;
    std::wcout <<L"当前所在目录是:"<< root->path->c_str()<<root->name->c_str()<<std::endl;


    // ***************************文件信息查看说明********************************

    // q:退出
    // w:返回上一级
    // p:查看当前位置下的文件
    // 数值:查看对应位置文件夹下的文件信息

    // 浏览文件信息
    file_instance* begin = root;
    std::string line;

    while(line!=std::string("q"))
    {
        std::cout << "option>>" <<std::endl;
        std::getline(std::cin,line);
        if(line==std::string("w"))
        {
            if(NULL!=begin->top){
                begin = begin->top;
                begin->Print();
            }
            else
            {
                std::wcout << "not exist" << std::endl;
            }
        }
        else if(line==std::string("p"))
        {
            if(NULL!=begin){
                begin->Print();
            }
            else
            {
                std::wcout << "not exist" << std::endl;
            }
        }
        else
        {
            int number = getNumber(line);
            if(number!=-1)
            {
                if(NULL!=begin)
                {
                    file_instance* target = begin->getPointToFileInstance(number);
                    if(NULL!=target)
                    {
                        begin = target;
                        target->Print();
                    }else
                    {
                        std::wcout << "not exist" << std::endl;
                    }
                }else
                {
                    begin = root->child;
                }
            }
        }
    }
    // ***************************结束********************************
    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值