您的位置:首页 > 其它

file : 遍历删除目录中的文件

2014-05-15 12:26 555 查看
在codeproject上见过遍历删除目录中的文件的函数,就是用findfile + deletefile来操作。

用来释放资源前,先删除资源目录的所有文件,防止不能释放新的资源文件.

e.g. 释放一个zip包, 解压zip包到数据目录中的资源子目录. 那下次释放前,为了防止资源文件是旧版,先删除,再释放。

今天,自己写了一个, 还蛮好用的~

BOOL DeleteFilePro(const WCHAR * pcFilePathName, BOOL bFileNeedExist = TRUE, eDeleteFile_method method = eDeleteFile_method_findfile_deletefile);
    BOOL DeleteFilePro_m1(const WCHAR * pcFilePathName, BOOL bFileNeedExist = TRUE);
    BOOL DeleteFilePro_m2(const WCHAR * pcFilePathName, BOOL bFileNeedExist = TRUE);


enum eDeleteFile_method
{
    eDeleteFile_method_unknown = 0,
    eDeleteFile_method_findfile_deletefile,
    edeletefile_method_shfileoperation_fo_delete,
};


BOOL DeleteFilePro(const WCHAR * pcFilePathName, BOOL bFileNeedExist, eDeleteFile_method method)
    {
        /// 方法1 : 用FindFile遍历删除, 要考虑遍历子文件夹, 支持通配符
        /// 方法2 : SHFileOperation + FO_DELETE
        /// 有时间可以比较一下这两种方法的用时, 现在先采用方法2, 用起来简单
        /// 但是, 如果删不掉文件,没有错误码可供观看, 在窗口没起来之前,这函数不好使

        BOOL    bDeleteFileOkOnce = FALSE;
        
        if ((NULL == pcFilePathName)
            || (bFileNeedExist && !IsFileExist(pcFilePathName)))
        {
            return FALSE;
        }

        switch (method)
        {
        case eDeleteFile_method_findfile_deletefile:
            bDeleteFileOkOnce = DeleteFilePro_m1(pcFilePathName, bFileNeedExist);
            break;

        case edeletefile_method_shfileoperation_fo_delete:
            bDeleteFileOkOnce = DeleteFilePro_m2(pcFilePathName, bFileNeedExist);
            break;

        default:
            break;
        }

        return bDeleteFileOkOnce;
    }

    BOOL DeleteFilePro_m1(const WCHAR * pcFilePathName, BOOL bFileNeedExist)
    {
        BOOL    bFind = TRUE;
        BOOL    bHavenFileSize = FALSE;
        BOOL    bDeleteFileOkOnce = FALSE;
        BOOL    bDeleteFileRc = FALSE;
        WIN32_FIND_DATA FindData;
        HANDLE  hFind = INVALID_HANDLE_VALUE;
        std::wstring    strDirNow = L"";
        std::wstring::size_type    nPos = std::wstring::npos;
        std::wstring    strFilePathNameCur = L"";
        std::wstring    strDirCur = L"";
        std::wstring    strFileShortName = L"";

        strDirNow = pcFilePathName;
        nPos = strDirNow.rfind(L'\\');
        strDirNow = strDirNow.substr(0, nPos);

        hFind = FindFirstFile(pcFilePathName, &FindData);
        while ((INVALID_HANDLE_VALUE != hFind) && bFind)
        {
            strFileShortName = _tcslen(FindData.cAlternateFileName) > 0 ? FindData.cAlternateFileName : FindData.cFileName;
            if ((FILE_ATTRIBUTE_DIRECTORY & FindData.dwFileAttributes) > 0)
            {
                if ((0 != _tcsicmp(FindData.cFileName, L"."))
                    && (0 != _tcsicmp(FindData.cFileName, L"..")))
                {
                    strDirCur = strDirNow;
                    strDirCur += L"\\";
                    strDirCur += strFileShortName.c_str();

                    strFilePathNameCur = strDirCur;
                    strFilePathNameCur += L"\\";
                    strFilePathNameCur += L"*.*";
                    bDeleteFileOkOnce = DeleteFilePro_m1(strFilePathNameCur.c_str(), bFileNeedExist);
                    if (bDeleteFileOkOnce)
                        bDeleteFileOkOnce = RemoveDirectoryW(strDirCur.c_str());
                }
            }
            else if ((FindData.nFileSizeHigh > 0) || (FindData.nFileSizeLow > 0))
            {
                bHavenFileSize = TRUE;
                strFilePathNameCur = strDirNow;
                strFilePathNameCur += L"\\";
                strFilePathNameCur += strFileShortName.c_str();

                bDeleteFileRc = DeleteFileW(strFilePathNameCur.c_str());
                if (!bDeleteFileOkOnce)
                    bDeleteFileOkOnce = bDeleteFileRc;
            }

            bFind = FindNextFileW(hFind, &FindData);
        }

END_DeleteFilePro_m1:
        SAFE_CLOSE_FILE_FIND_HANDLE(hFind);

        if (!bHavenFileSize)
            return TRUE; ///< . or .., need not delete any file.
        else
            return bDeleteFileOkOnce; ///< the real delete result
    }

    BOOL DeleteFilePro_m2(const WCHAR * pcFilePathName, BOOL bFileNeedExist)
    {
        WCHAR szFilePathName[MAX_PATH] = {L'\0'};
        SHFILEOPSTRUCTW FileOp; 

        ZeroMemory(szFilePathName, sizeof(szFilePathName));
        _tcscpy_s(szFilePathName, SIZEOF_ARRAY(szFilePathName), pcFilePathName);

        ZeroMemory(&FileOp, sizeof(SHFILEOPSTRUCTW)); 
        FileOp.fFlags |= FOF_SILENT;            /*不显示进度*/
        FileOp.fFlags |= FOF_NOERRORUI;         /*不报告错误信息*/
        FileOp.fFlags |= FOF_NOCONFIRMATION;    /*直接删除,不进行确认*/
        FileOp.hNameMappings = NULL;
        FileOp.hwnd = NULL;
        FileOp.lpszProgressTitle = NULL;
        FileOp.wFunc = FO_DELETE;
        FileOp.pFrom = szFilePathName;          /*要删除的目录,必须以2个\0结尾*/
        FileOp.pTo = NULL; 
        FileOp.fFlags &= ~FOF_ALLOWUNDO;      

        return (0 == SHFileOperationW(&FileOp));
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐