Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1619896
  • 博文数量: 441
  • 博客积分: 20087
  • 博客等级: 上将
  • 技术积分: 3562
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-19 15:35
文章分类

全部博文(441)

文章存档

2014年(1)

2012年(1)

2011年(8)

2010年(16)

2009年(15)

2008年(152)

2007年(178)

2006年(70)

分类:

2010-06-30 16:31:18

 用SHFileOperation拷贝文件是整体的全部拷贝,可有的时候,想进行过滤拷贝,有的文件不想拷贝,有的文件夹不想拷贝,或者是有特定扩展名的文件不想拷贝, 比如.obj, .ncb文件等。下面的函数便能实现以上的过滤拷贝功能。


void string_replace(string & strBig, const string & strsrc, const string &strdst)
{
    string::size_type pos=0;
    string::size_type srclen=strsrc.size();
    string::size_type dstlen=strdst.size();
    while( (pos=strBig.find(strsrc, pos)) != string::npos)
    {
        strBig.erase(pos, srclen);
        strBig.insert(pos, strdst);
        pos += dstlen;
    }
}

void PathConvert(string& strAbsPath, string strRelativePath)
{
    int nFind = strRelativePath.find("..");
    if ( nFind < 0 )
    {
        strAbsPath = strRelativePath;
        return;
    }
    string str1 = strRelativePath.substr(0, nFind);
    string str2 = strRelativePath.substr(nFind, strRelativePath.length() - nFind);

    TCHAR szAbsPath[MAX_PATH] = {0};
    PathCombine(szAbsPath, str1.c_str(), str2.c_str());
    strAbsPath = szAbsPath;
}

void PrepareCopyFolders(vector<string>& listFolders, string strSrcFolder,
                        vector<string> listNotCopyFolders)
{
    TCHAR szFindForder[MAX_PATH] = {0};
    wsprintf(szFindForder, TEXT("%s\\*.*"), strSrcFolder.c_str());

    WIN32_FIND_DATA wfd;
    HANDLE hFileFind = FindFirstFile(szFindForder, &wfd);
    if ( hFileFind == INVALID_HANDLE_VALUE )
        return;

    BOOL bOK = TRUE;
    while ( bOK )
    {
        if ( lstrcmpi(wfd.cFileName, TEXT(".")) == 0 ||
             lstrcmpi(wfd.cFileName, TEXT("..")) == 0 )
        {
            bOK = FindNextFile(hFileFind, &wfd);
            continue;
        }

        BOOL bCopy = TRUE;
        int nCount = listNotCopyFolders.size();
        for ( int i = 0; i < nCount; i++ )
        {
            if ( lstrcmpi(wfd.cFileName, listNotCopyFolders[i].c_str()) == 0 )
            {
                bCopy = FALSE;
                break;
            }
        }
        if ( !bCopy )
        {
            bOK = FindNextFile(hFileFind, &wfd);
            continue;
        }

        string strFindFoler = strSrcFolder + string("\\") + string(wfd.cFileName);

        if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
        {
            listFolders.push_back(strFindFoler);
            PrepareCopyFolders(listFolders, strFindFoler, listNotCopyFolders);
        }
        bOK = FindNextFile(hFileFind, &wfd);
    }
}

bool    FilterCopy(string strSrcFolder, string strDstFolder,
                 vector<string> listNotCopyFolders,
                 vector<string> listNotCopyFilesExt,
                 vector<string> listNotCopyFiles)
{
    int nFind = strSrcFolder.find(':');
    if ( nFind <= 0 )
        return false;
    nFind = strDstFolder.find(':');
    if ( nFind <= 0 )
        return false;
    strDstFolder += string("\\");

    PathConvert(strSrcFolder, strSrcFolder);
    PathConvert(strDstFolder, strDstFolder);

    nFind = strDstFolder.find('\\', 0);
    while ( nFind > 0 )
    {
        nFind = strDstFolder.find('\\', nFind + 1);
        if ( nFind < 0 )
            break;
        string strSubFolder = strDstFolder.substr(0, nFind);
        CreateDirectory(strSubFolder.c_str(), NULL);
    }

    vector<string> listSrcFolders;

    listSrcFolders.push_back(strSrcFolder);
    PrepareCopyFolders(listSrcFolders, strSrcFolder, listNotCopyFolders);

    int i;
    int nCount = listSrcFolders.size();
    for ( i = 0; i < nCount; i++ )
    {
        string str = listSrcFolders[i];
        string_replace(str, strSrcFolder, strDstFolder);
        CreateDirectory(str.c_str(), NULL);

        TCHAR szFindFolder[MAX_PATH] = {0};
        wsprintf(szFindFolder, TEXT("%s\\*.*"), listSrcFolders[i].c_str());
        WIN32_FIND_DATA wfd;
        HANDLE hFileFind = FindFirstFile(szFindFolder, &wfd);
        if ( INVALID_HANDLE_VALUE == hFileFind )
            continue;

        BOOL bOK = TRUE;
        while ( bOK )
        {
            if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            {
                bOK = FindNextFile(hFileFind, &wfd);
                continue;
            }

            BOOL bCopy = TRUE;
            int nNotCopyCount = listNotCopyFiles.size();
            for ( int j = 0; j < nNotCopyCount; j++ )
            {
                if ( lstrcmpi(wfd.cFileName, listNotCopyFiles[j].c_str()) == 0 )
                {
                    bCopy = FALSE;
                    break;
                }
            }
            if ( !bCopy )
            {
                bOK = FindNextFile(hFileFind, &wfd);
                continue;
            }

            bCopy = TRUE;
            nNotCopyCount = listNotCopyFilesExt.size();
            for ( int k = 0; k < nNotCopyCount; k++ )
            {
                string strFile = string(wfd.cFileName);
                nFind = strFile.rfind('.');
                if ( nFind < 0 )
                    continue;
                strFile = strFile.substr(nFind, strFile.length() - nFind);
                if ( lstrcmpi(strFile.c_str(), listNotCopyFilesExt[k].c_str()) == 0 )
                {
                    bCopy = FALSE;
                    break;
                }
            }
            if ( !bCopy )
            {
                bOK = FindNextFile(hFileFind, &wfd);
                continue;
            }

            TCHAR szSrcFile[MAX_PATH] = {0};
            TCHAR szDstFile[MAX_PATH] = {0};
            wsprintf(szSrcFile, TEXT("%s\\%s"), listSrcFolders[i].c_str(), wfd.cFileName);
            wsprintf(szDstFile, TEXT("%s\\%s"), str.c_str(), wfd.cFileName);

            if ( !CopyFile(szSrcFile, szDstFile, FALSE) )
                return false;

            bOK = FindNextFile(hFileFind, &wfd);
        }
    }

    return true;
}


调用举例:

    vector<string> listNotCopyFolders;
    vector<string> listNotCopyFilesExt;
    vector<string> listNotCopyFiles;

    listNotCopyFolders.push_back(string(".svn"));
    listNotCopyFolders.push_back(string("res"));

    listNotCopyFilesExt.push_back(string(".o"));
    listNotCopyFilesExt.push_back(string(".db"));
    listNotCopyFilesExt.push_back(string(".mine"));

    listNotCopyFiles.push_back(string("hello.bmp"));
    listNotCopyFiles.push_back(string("xxx.ss.r395"));
    listNotCopyFiles.push_back(string("yyy.ss.r407"));

    FilterCopy("c:\\abc", "d:\\efg\\..\\abc", listNotCopyFolders,
        listNotCopyFilesExt, listNotCopyFiles);


如果目标目录不存在,程序会自动创建目标目录,可以有多层。
vector<string> listNotCopyFolders;
代表过滤的目录列表, 只要符合这个目录名称,则都不拷贝

vector
<string> listNotCopyFilesExt;
代表过滤的文件扩展名列表,只要符合这个扩展名,则都不拷贝

vector<string> listNotCopyFiles;

特定的文件过滤列表,只要符合这个列表中的文件名,都不拷贝

同时,程序支持相对路径,比如目标路径:d:\efg\..\abc
会自动被解析为:d:\abc

author: thinker
e-mail: cnhnyugmail.com
qq: 94483026

阅读(1364) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~