代码之家  ›  专栏  ›  技术社区  ›  Geek

删除以子字符串开头的文件

  •  0
  • Geek  · 技术社区  · 6 年前

    我想删除所有以子字符串开头的文件。

      CString Formatter = _T("C:\\logs\\test\\test_12-12-2018_1*.*");     
      DeleteFile(Formatter);
    

    我打算删除以下带有上述代码的文件

        C:\logs\test\test_12-12-2018_1_G1.txt
        C:\logs\test\test_12-12-2018_1_G2.txt
        C:\logs\test\test_12-12-2018_1_G3.txt
        C:\logs\test\test_12-12-2018_1_G4.txt
    

    当我从GetLastError检查错误时,我得到错误\无效的\名称。

    知道怎么解决这个问题吗?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Govind Parmar vitaly.v.ch    6 年前

    DeleteFile 不带通配符。看起来你需要的是 FindFirstFile / FindNextFile / FindClose 循环将通配符转换为完整文件名列表。

    #include <windows.h>
    #include <pathcch.h>
    #pragma comment(lib, "pathcch.lib")
    
    // (In a function now)
    WIN32_FIND_DATAW wfd;
    WCHAR wszPattern[MAX_PATH];
    HANDLE hFind;
    INT nDeleted = 0;
    PathCchCombine(wszPattern, MAX_PATH, L"C:\\Logs\\Test", L"test_12-12-2018_1*.*");
    SetCurrentDirectoryW(L"C:\\Logs\\Test");
    
    hFind = FindFirstFileW(wszPattern, &wfd);
    if(hFind == INVALID_HANDLE_VALUE)
    {
        // Handle error & exit
    }
    do
    {
        DeleteFileW(wfd.cFileName);
        nDeleted++;
    } 
    while (FindNextFileW(hFind, &wfd));
    FindClose(hFind);
    
    wprintf(L"Deleted %d files.\n", nDeleted);
    

    注意 PathCchCombine , FindFirstFileW DeleteFileW 可以全部失败,并且健壮的代码将检查它们的返回值并适当地处理失败。此外,如果 FindNextFileW 返回0,最后一个错误代码不是 ERROR_NO_MORE_FILES ,然后由于实际错误(不是因为没有什么可查找的)而失败,这也需要处理。

    另外,如果速度是您的一个问题(您在文章中关于删除同一目录中的四个文件的示例似乎不需要它),请替换该行 hFind = FindFirstFileW(...) 用:

    hFind = FindFirstFileExW(wszPattern, FindExInfoBasic, (LPVOID)&wfd, FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH);
    
        2
  •  2
  •   Jerry Coffin    6 年前

    虽然你 可以 搜索文件名,然后调用 DeleteFile 对于每一个,我的建议是使用一个windows shell函数来代替。

    例如,您可以使用如下代码:

    #define _WIN32_IE 0x500
    
    #include <windows.h>
    #include <shellapi.h>
    #include <shlobj.h>
    #include <iostream>
    #include <string>
    
    static char const *full_path(std::string const &p) {
        static char path[MAX_PATH+2] = {0};
        char *ignore;
        GetFullPathName(p.c_str(), sizeof(path), path, &ignore);
        return path;
    }
    
    static int shell_delete(std::string const &name) {
        SHFILEOPSTRUCT op = { 0 };
    
        op.wFunc = FO_DELETE;
        op.pFrom = full_path(name);
        op.fFlags = FOF_ALLOWUNDO | FOF_SILENT | FOF_WANTNUKEWARNING | FOF_NOCONFIRMATION;
        return !SHFileOperation(&op);
    }
    
    int main(int argc, char **argv) {
    
        if ( argc < 2) {
            fprintf(stderr, "Usage: delete <filename> [filename ...]");
            return 1;
        }
    
        for (int i=1; i<argc; i++)
            shell_delete(argv[i]);    
    }
    

    一个明显的优点是你可以通过 FOF_ALLOWUNDO 标记(如上面代码中所示),它将文件移动到回收站,而不是永久删除。当然,如果您想对文件进行润色,可以省略这个标志。

    根据您所做的,还有一些其他标记可能很方便,例如 FOF_FILESONLY ,只删除文件,而不删除可能与指定的通配符匹配的目录,以及 FOF_NORECURSION 使它完全不递归到子目录中。

    微软认为 SHFileOperation 已过时,并且(在Windows Vista中,如果内存可用)已将其“替换为” IFileOperation . IFIL手术 不过,它是一个COM接口,所以除非您在代码中的其他地方使用COM,否则很有可能使用它会为(至少在本例中)很少或根本没有实际优势而增加相当多的额外工作。尤其是你已经在使用COM了,不过,这可能值得考虑。