Вопрос по c, unix, c++, linux – Как удалить все файлы в папке, но не удалить папку, используя стандартные библиотеки NIX?

19

Я пытаюсь создать программу, которая удаляет содержимое папки / tmp, я использую C / C ++ на Linux.

system("exec rm -r /tmp")

удаляет все в папке, но также удаляет папку, которую я не хочу.

Есть ли способ сделать это с помощью своего рода скрипта bash, называемого черезsystem(); или есть прямой способ, которым я могу сделать это в C / C ++?

Мой вопрос похож на этот, но я не на OS X ...как удалить все файлы в папке, но не саму папку?

rm -r /tmp/* удалит содержимое папки. AusCBloke
@AusCBloke: Хм ... это удалит всеvisible файлы в папке (т.е. те, которые* расширяется до), но не удаляет файлы, начинающиеся с. David Rodríguez - dribeas
@ DavidRodr & # xED; guez-dribeas: Кстати, удаление содержимого / tmp может повредить чему-нибудь? Finding Nemo 2 is happening.
@ DavidRodr & # xED; guez-dribeas: О да, хорошая мысль. AusCBloke
Если вы хотите инвестировать в будущее, вы можете использоватьboost::filesystem перебрать и удалить каждый. chris

Ваш Ответ

7   ответов
3

system("exec find /tmp -mindepth 1 -exec rm {} ';'");
Любой звонок в Систему небезопасенsecureco,ding.cert.org/confluence/pages/…
@ DavidRodr & # xED; guez-dribeas, ты прав. Я отредактировал свой ответ соответственно.
Хм ... это удалит все видимые файлы в папке (то есть те, которые * расширяются до), но не удалит ни один файл, начинающийся с.
0

nftw (3), Сначала сделайте проход, чтобы собрать набор путей к файлам для удаления. Тогда используйтеunlink (для не-каталогов) иRmDir (2) во втором проходе

15

В C / C ++ вы можете сделать:

system("exec rm -r /tmp/*")

В Bash вы можете сделать:

rm -r /tmp/*

Это удалит все, что находится внутри / tmp, но не само / tmp.

Любой звонок в «систему» от С не является безопасным.securecoding.cert.org/confluence/pages/…
@jackb: я согласен. Однако (так как вы проголосовали) имейте в виду, что ОПdid спросите, & quot; ... Есть ли способ сделать это с помощью какого-то bash-скрипта, вызываемого через систему ... & quot;
Хм ... это удалит все видимые файлы в папке (то есть те, которые * расширяются до), но не удалит ни один файл, начинающийся с.
Читайте внимательно в следующий разor is there a direct way i can do this in C/C++?.
Работает замечательно, спасибо! Finding Nemo 2 is happening.
3

* Символ вы можете удалить все файлы с любым типом расширения.

system("exec rm -r /tmp/*")

Хм ... это удалит все видимые файлы в папке (то есть те, которые * расширяются до), но не удалит ни один файл, начинающийся с.
1

что это очень старый вопрос, но, основываясь на отличном ответе Демитри, я создал функцию, которая при желании рекурсивно удаляет файлы в подпапках.

Это также делаетsome обработка ошибок, в том, что она возвращается обратно errno. Заголовок функции написан для разбора doxygen. Эта функция работает в простых примерах, которые я использовал, и удаляет скрытые папки и скрытые файлы.

Я надеюсь, что это поможет кому-то еще в будущем

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#define SUCCESS_STAT 0

/**
 * checks if a specific directory exists
 * @param dir_path the path to check
 * @return if the path exists
 */
bool dirExists(std::string dir_path)
{
    struct stat sb;

    if (stat(dir_path.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode))
        return true;
    else
        return false;
}

/**
 * deletes all the files in a folder (but not the folder itself). optionally
 * this can traverse subfolders and delete all contents when recursive is true
 * @param dirpath the directory to delete the contents of (can be full or
 * relative path)
 * @param recursive true = delete all files/folders in all subfolders
 *                  false = delete only files in toplevel dir
 * @return SUCCESS_STAT on success
 *         errno on failure, values can be from unlink or rmdir
 * @note this does NOT delete the named directory, only its contents
 */
int DeleteFilesInDirectory(std::string dirpath, bool recursive)
{
    if (dirpath.empty())
        return SUCCESS_STAT;

    DIR *theFolder = opendir(dirpath.c_str());
    struct dirent *next_file;
    char filepath[1024];
    int ret_val;

    if (theFolder == NULL)
        return errno;

    while ( (next_file = readdir(theFolder)) != NULL )
    {
        // build the path for each file in the folder
        sprintf(filepath, "%s/%s", dirpath.c_str(), next_file->d_name);

        //we don't want to process the pointer to "this" or "parent" directory
        if ((strcmp(next_file->d_name,"..") == 0) ||
            (strcmp(next_file->d_name,"." ) == 0) )
        {
            continue;
        }

        //dirExists will check if the "filepath" is a directory
        if (dirExists(filepath))
        {
            if (!recursive)
                //if we aren't recursively deleting in subfolders, skip this dir
                 continue;

            ret_val = DeleteFilesInDirectory(filepath, recursive);

            if (ret_val != SUCCESS_STAT)
            {
                closedir(theFolder);
                return ret_val;
            }
        }

        ret_val = remove(filepath);
        //ENOENT occurs when i folder is empty, or is a dangling link, in
        //which case we will say it was a success because the file is gone
        if (ret_val != SUCCESS_STAT && ret_val != ENOENT)
        {
            closedir(theFolder);
            return ret_val;
        }

    }

    closedir(theFolder);

    return SUCCESS_STAT;
}
44
#include <stdio.h>
#include <dirent.h>

int main()
{
    // These are data types defined in the "dirent" header
    DIR *theFolder = opendir("path/of/folder");
    struct dirent *next_file;
    char filepath[256];

    while ( (next_file = readdir(theFolder)) != NULL )
    {
        // build the path for each file in the folder
        sprintf(filepath, "%s/%s", "path/of/folder", next_file->d_name);
        remove(filepath);
    }
    closedir(theFolder);
    return 0;
}

system() или что-то в этом роде - это слишком много усилий, чтобы сделать что-то очень простое, и оно делает ненужные предположения (и зависимости) о том, что доступно в системе.

Хм ... ответ, который на самом деле работает для скрытых файлов и не требует оболочки! +1 (хотя с другой стороны он не будет рекурсивно удалять каталоги и не обрабатывает ошибки ...)
вы, вероятно, хотите установитьif (0==strcmp(next_file->d_name, ".") || 0==strcmp(next_file->d_name, "..")) { continue; } в начале оператора while, если вы не хотите удалять файлы "." и & quot; .. & quot;
Код не компилируется
Лучший ответ :)
1

system("rm -r /tmp/* /tmp/.*");
system("find /tmp -mindepth 1 -delete");

Но что делать, если 'rm' или "найти" Утилиты недоступны для sh ?, лучше иди "ftw" и "удалить":

#define _XOPEN_SOURCE 500
#include <ftw.h>

static int remove_cb(const char *fpath, const struct stat *sb, int typeFlag, struct FTW *ftwbuf)
{
    if (ftwbuf->level)
        remove(fpath);
    return 0;
}

int main(void)
{
    nftw("./dir", remove_cb,  10, FTW_DEPTH);
    return 0;
}

Похожие вопросы