chdir导致无法删除最后一个子文件夹

#include<iostream>
#include<string>
#include<set>
#include<windows.h>
#include<strsafe.h>
#include<direct.h>

//迭代输出目录下所有文件
void recurseFiles(const std::string& path, std::set<std::string>& files)
{
    WIN32_FIND_DATA fileInfo;
    HANDLE h_find = NULL;
    std::string assetPath;
    h_find = FindFirstFileA(assetPath.assign(path).append("\\*").c_str(), &fileInfo);
    if(h_find != INVALID_HANDLE_VALUE)
    {
        _chdir(path.c_str());// 此处关闭即可正常删除整个目录,否则会留下目录中最后一个子目录
        do
        {
            if(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if(strcmp(fileInfo.cFileName, ".") && strcmp(fileInfo.cFileName, ".."))
                {
                    recurseFiles(assetPath.assign(path).append("\\").append(fileInfo.cFileName), files);
                }
            }
            else
            {
                files.insert(assetPath.assign(path).append("\\").append(fileInfo.cFileName));
            }
        } while(FindNextFileA(h_find, &fileInfo]));
    }
    FindClose(h_find);
}

// 输出错误信息
void reportError()
{
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD lastError = GetLastError();
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        lastError,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf,
        0, NULL
    );

    lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT, lstrlen((LPCTSTR)lpMsgBuf) + MAX_PATH) * sizeof(TCHAR));

    StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), TEXT("%s failed with error %d : %s"), "RemoveAll", lastError, lpMsgBuf);

    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}

// 删除整个path目录
void removeAllFiles(const std::string& path)
{
    WIN32_FIND_DATA fileInfo;
    HANDLE h_find = NULL;
    std::string assetPath;
    h_find = FindFirstFileA(assetPath.assign(path).append("\\*").c_str(), &fileInfo);
    if(h_find != INVALID_HANDLE_VALUE)
    {
        do
        {
            if(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if(strcmp(fileInfo.cFileName, ".") && strcmp(fileInfo.cFileName, ".."))
                {
                    recurseFiles(assetPath.assign(path).append("\\").append(fileInfo.cFileName), files);
                }
            }
            else
            {
                DWORD dwAttribute = ::GetFileAttributesA(assetPath.assign(path).append("\\").append(fileInfo.cFileName).c_str());
                if(dwAttribute & FILE_ATTRIBUTE_READONLY)
                {
                    dwAttribute &= ~FILE_ATTRIBUTE_READONLY;
                    SetFileAttributeA(assetPath.c_str(), dwAttribute);
                }
                if(!DeleteFileA(assetPath.c_str()))
                {
                    reportError();
                }
            }
        } while(FindNextFileA(h_find, &fileInfo));
    }

    FindClose(h_find);

    if(!RemoveDirectoryA(path.c_str()))
    {
        reportError();
    }
}

void main()
{
    std::string sourcePath("D:\\Sheldon\\My Project");
    std::set<std::string> allFiles;
    recurseFiles(sourcePath, allFiles);
    for(auto it = allFiles.begin(); it != allFiles.end(); it++)
    {
        std::cout << *it << std::endl;
    }

    removeAllFiles(sourcePath);
    getchar();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值