C++文件查找、创建、文件夹操作

 
C++文件查找、创建、文件夹操作
 
 
知识点:

C++用 _findfirst 和 _findnext 查找文件

 
一、这两个函数均在io.h里面。
二、首先了解一下一个文件结构体:
struct _finddata_t {
   unsigned    attrib;
   time_t      time_create;  
   time_t      time_access;  
   time_t      time_write;
   _fsize_t    size;
   char        name[260];
};
time_t,其实就是long
而_fsize_t,就是unsigned long
现在来解释一下结构体的数据成员吧。
attrib,就是所查找文件的属性:_A_ARCH(存档)、_A_HIDDEN(隐藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、 _A_SUBDIR(文件夹)、_A_SYSTEM(系统)。
time_create、time_access和time_write分别是创建文件的时间、最后一次访问文件的时间和文件最后被修改的时间。
size:文件大小
name:文件名。
三、用 _findfirst 和 _findnext 查找文件
1、_findfirst函数:long _findfirst(const char *, struct _finddata_t *);
第一个参数为文件名,可以用"*.*"来查找所有文件,也可以用"*.cpp"来查找.cpp文件。第二个参数是_finddata_t结构体指针。若查找成功,返回文件句柄,若失败,返回-1。
2、_findnext函数:int _findnext(long, struct _finddata_t *);
第一个参数为文件句柄,第二个参数同样为_finddata_t结构体指针。若查找成功,返回0,失败返回-1。
3、_findclose()函数:int _findclose(long);
只有一个参数,文件句柄。若关闭成功返回0,失败返回-1。
 
 
#include <io.h>   // _finddata_t   _findfirst   _findnext  _findclose
#include <iostream> //cout
#include <fstream>  //ofstream
#include <vector>   //vector
#include <time.h>
#include <direct.h>
#include < stdio.h >
using namespace std;
bool transfer( string fileName, int exeNum);
void dfsFolder( string folderPath, ofstream& fout);
void ListDirDetail( const char* folderPath);
void ListDirPath( const string folderPath, vector < string>* filestruct);
bool my_create_dir(std:: string path);
void cleanDir( string folderPath);
int main()
{
    _finddata_t file;
    int k;
    long HANDLE;
    k = HANDLE = _findfirst( R"(D:\BaiduNetdiskDownload\*)", &file);
    while (k != -1)
    {
        cout << file.name << endl;
        k = _findnext(HANDLE, &file);
    }
    _findclose(HANDLE);
   
    cout << R"(----------------------)" << endl;
    cout << "文件列表:" << endl;
    ListDirDetail( R"(D:\BaiduNetdiskDownload)");
    cout << R"(----------------------)" << endl;
    transfer( "C:\\Windows\\*.exe", 0);
    cout << R"(----------------------)" << endl;
    ofstream o_fstream;
    char* psavestudir = ( char *)malloc( sizeof( char)*512);
    _getcwd(psavestudir, 512);  //获取当前的工作路径
    string savestudir = psavestudir;
    savestudir = savestudir + "\\Log";
    my_create_dir(savestudir);
    savestudir = savestudir + "\\fileStu.txt";
    //o_fstream.open(".\\Log\\fileStu.txt", ios::out| ios::app);
    o_fstream.open(savestudir, ios::out | ios::app);
    o_fstream << R"(FileStruct is)" << ":\n";
    dfsFolder( R"(D:\BaiduNetdiskDownload)", o_fstream);
    o_fstream.close();
   
   
    //vector
    vector < string> filestruct;
    filestruct.reserve(10);
    ListDirPath( R"(D:\BaiduNetdiskDownload)", &filestruct);
    //保存在指定文件中
    string mylogpath( R"(D:\myvcproject\C_CppProject\Log\mytextlog)");
    my_create_dir(mylogpath);
    o_fstream.open(mylogpath + "\\dirStu.txt", ios::out | ios::app);
    o_fstream << R"(dirStruct is)" << ":\n";
    for ( uint32_t i = 0; i < filestruct.size(); i++)
        o_fstream << filestruct [i ] <<endl;
    o_fstream.close();
    //询问是否删除
    char choose;
    cout << "Y/N" << endl;
    cin >> choose;
    if (choose == 'Y')
    {
        cleanDir( string( R"(D:\myvcproject)"));
    }
    return 0;
}
//_findfirst 函数返回的是匹配到文件的句柄,数据类型为long。
//遍历过程可以指定文件类型,这通过FileName的赋值来实现,例如要遍历C : \WINDOWS下的所有.exe文件
bool transfer( string fileName, int exeNum)
{
    _finddata_t fileInfo;
    long handle = _findfirst( fileName.c_str(), &fileInfo);
    if (handle == -1L)
    {
        cerr << "failed to transfer files" << endl;
        return false;
    }
    do
    {
        exeNum++;
        cout << fileInfo.name << endl;
    } while ( _findnext(handle, &fileInfo) == 0);
    cout << " .exe files' number:  " << exeNum << endl;
    _findclose(handle);
    return true;
}
//遍历文件夹及其子文件夹下所有文件。操作系统中文件夹目录是树状结构,使用深度搜索策略遍历所有文件。用到_A_SUBDIR属性
//在判断有无子目录的if分支中,由于系统在进入一个子目录时,匹配到的头两个文件(夹)是"."(当前目录),".."(上一层目录)。
//需要忽略掉这两种情况。当需要对遍历到的文件做处理时,在else分支中添加相应的代码就好
void dfsFolder( string folderPath, ofstream& fout)
{
    _finddata_t FileInfo;
    string strfind = folderPath + "\\*";
    long Handle = _findfirst(strfind.c_str(), &FileInfo);
    if (Handle == -1L)
    {
        cerr << "can not match the folder path" << endl;
        //exit(-1);
    }
    do {
        //判断是否有子目录 
        if (FileInfo.attrib & _A_SUBDIR)
        {
            //这个语句很重要 
            if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
            {
                string newPath = folderPath + "\\" + FileInfo.name;
                dfsFolder(newPath, fout);
            }
        }
        else
        {
            fout << folderPath.c_str() << "\\" << FileInfo.name << "\n";
            //cout << folderPath.c_str() << "\\" << FileInfo.name << endl;
        }
    } while ( _findnext(Handle, &FileInfo) == 0);
    _findclose(Handle);
    //fout.close();
}
//列出当前文件夹下所有的子文件夹及文件的属性
void ListDirDetail( const char * folderPath)
{
    _finddata_t FileInfo;
    string strfind = folderPath;
    strfind = strfind + "\\*";
    long Handle = _findfirst(strfind.c_str(), &FileInfo);
    if (Handle == -1L)
    {
        cerr << "can not match the folder path" << endl;
        //exit(-1);
    }
    do {
        cout << FileInfo.name << "\t";
        cout << FileInfo.size << "bytes \t";
        if (FileInfo.attrib & _A_NORMAL)
            cout << "  普通文件  " << "\t";
        if (FileInfo.attrib & _A_RDONLY)
            cout << "  只读文件  " << "\t";
        if (FileInfo.attrib & _A_HIDDEN)
            cout << "  隐藏文件  " << "\t";
        if (FileInfo.attrib & _A_SYSTEM)
            cout << "  系统文件  " << "\t";
        if (FileInfo.attrib & _A_SUBDIR)
            cout << "  子目录  " << "\t";
        if(FileInfo.attrib & _A_ARCH)
            cout << "  存档文件  " << "\t";
        tm tmLocal;
        //写入时间
        localtime_s(&tmLocal, &FileInfo.time_write);
        cout  << (tmLocal.tm_year+1900) << "-" << tmLocal.tm_mon << "-" <<tmLocal.tm_mday << "\t";
        cout << endl;
    } while ( _findnext(Handle, &FileInfo) == 0);
    _findclose(Handle);
}
//列出当前文件夹下所有子文件夹并放到一个vector中
void ListDirPath( const string folderPath, vector < string> * filestruct)
{
    _finddata_t FileInfo;
    string strfind = folderPath + "\\*";
    filestruct->push_back( folderPath + string( "\\"));
    long Handle = _findfirst(strfind.c_str(), &FileInfo);
    if (Handle == -1L)
    {
        cerr << "can not match the folder path" << endl;
        //exit(-1);
    }
    do {
        //这个语句很重要 
        if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
        {
            if (FileInfo.attrib & _A_SUBDIR) //判断是否有子目录
            {
                string newPath = folderPath + "\\" + FileInfo.name;
                ListDirPath(newPath, filestruct);
            }
        }
    } while ( _findnext(Handle, &FileInfo) == 0);
   
    _findclose(Handle);
}
//创建多级目录
bool my_create_dir(std:: string path)
{
    int m = 0, n;
    string str1, str2, str3;
    str1 = path;
    str2 = str1.substr(0, 2);
    str1 = str1.substr(3, str1.size());
    while (m >= 0)
    {
        m = str1.find( '\\');
        str2 += '\\' + str1.substr(0, m);
        n = _access(str2.c_str(), 0); //判断该目录是否存在
        if (n == -1)
        {
            if (_mkdir(str2.c_str()) != 0)     //创建目录
            {
                return false;
            }
        }
        str1 = str1.substr(m + 1, str1.size());
    }
    return true;
}
/*
// 检查文件夹是否存在不存在就创建一个
//path为绝对路径,例如E:\123\432\123
bool SavePathCheack(std::string path)
{
    if (path.length() <= 0)
        return false;
    //File aFile;
    errno_t err = 0;
    // Check for existence.  
    if ((err = _access_s(path.c_str(), 0)) != 0)
    {
        if (!my_create_dir(path)) //创建文件夹
            return false;
        else
        {
            std::cout << "创建文件夹成功" << path << std::endl;
            return true;
        }
    }
    else
        std::cout << path << "文件夹已经存在" << std::endl;
    return true;
}
*/
void cleanDir( string folderPath)
{
    _finddata_t FileInfo;
    string folderp = folderPath + "\\*";
    long Handle = _findfirst(folderp.c_str(), &FileInfo);
    //如果该路径不存在
    if (Handle == -1L)
    {
        cerr << "can not match the folder path" << endl;
        //exit(-1);
    }
    do
        if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
        {
            string newPath = folderPath + "\\" + FileInfo.name;
            if (FileInfo.attrib & _A_SUBDIR) //判断是否有子目录
            {
                cleanDir(newPath);
                _rmdir(newPath.c_str());
            }
            else
            {
                remove(newPath.c_str());
            }
        }
    } while ( _findnext(Handle, &FileInfo) == 0);
    _findclose(Handle);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值