DeleteFile以子字符串开头

时间:2019-02-11 15:48:34

标签: c++ winapi

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

  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检查错误时,我得到ERROR_INVALID_NAME。

有什么解决方法吗?

2 个答案:

答案 0 :(得分:2)

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);

请注意,PathCchCombineFindFirstFileWDeleteFileW都可能失败,而健壮的代码将检查它们的返回值并适当地处理失败。另外,如果FindNextFileW返回0并且最后一个错误代码不是ERROR_NO_MORE_FILES,则它由于实际错误而失败(不是因为没有剩余可找的东西),因此也需要处理

此外,如果您关心速度(您的帖子中关于删除同一目录中的四个文件的示例似乎并不需要),请用以下内容替换行hFind = FindFirstFileW(...)

hFind = FindFirstFileExW(wszPattern, FindExInfoBasic, (LPVOID)&wfd, FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH);

答案 1 :(得分:2)

尽管您可以 搜索文件名,然后分别为每个文件调用<div class="wrapper"> <div class="row-one"> <div class="row-wrapper"> <p>TOP CONTENT</p> <div class="card"> <p>Im a card </p> <div class="dropdown"> <h1>DROPDOWN</h1> <p>item</p> <p>item</p> <p>item</p> <p>item</p> <p>item</p> </div> </div> </div> </div> <div class="row-two"> <p>...content</p> <p>...content</p> <p>...content</p> </div> </div>,但我的建议是改为使用Windows Shell函数之一来完成工作。 / p>

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

DeleteFile

一个明显的好处是,您可以传递#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,仅删除文件,而不删除可能与您指定的通配符匹配的目录,以及{{1} },使其完全不递归到子目录中。

Microsoft认为FOF_FILESONLY已过时,并已(在Windows Vista中,如果有内存的话)用IFileOperation“替换”了它。 FOF_NORECURSION是一个COM接口,因此,除非您在代码中的其他地方使用COM,否则很有可能使用它会为(至少在这种情况下)很少或根本没有实际添加大量的额外工作。优点。特别是您已经在使用COM,但是,这可能值得考虑。