DeleteFile, которые начинаются с подстроки - PullRequest
0 голосов
/ 11 февраля 2019

Я хочу удалить все файлы, которые начинаются с подстроки.

  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 голосов
/ 11 февраля 2019

Хотя вы можете искать имена файлов, а затем вызывать DeleteFile для каждого из них по отдельности, я бы посоветовал использовать вместо этого одну из функций оболочки Windows.

Например, вы можете использовать код, подобный следующему:

#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, чтобы он вообще не возвращался в подкаталоги.

Microsoft считает SHFileOperation устаревшим и имеет (в Windows Vista, если память служит)«заменил» его на IFileOperation.IFileOperation - это интерфейс COM, поэтому, если вы не используете COM в другом месте своего кода, очень велики шансы, что его использование добавит изрядное количество дополнительной работы для (по крайней мере, в этом случае) небольшого или никакого реального преимущества.Тем более, что вы уже используете COM, однако, возможно, стоит подумать.

0 голосов
/ 11 февраля 2019

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...