如何删除文件夹中的所有文件,但不删除使用NIX标准库的文件夹?

时间:2012-06-13 02:32:34

标签: c++ c linux unix

我正在尝试创建一个删除/ tmp文件夹内容的程序,我在linux上使用C / C ++。

system("exec rm -r /tmp")

删除文件夹中的所有内容,但它也删除了我不想要的文件夹。

有没有办法通过某种bash脚本来做到这一点,通过system()调用;还是有直接的方式我可以在C / C ++中做到这一点?

我的问题与此类似,但我不在OS X上...... how to delete all files in a folder, but not the folder itself?

8 个答案:

答案 0 :(得分:45)

#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()或类似的东西生成新的shell - 这样做的开销非常简单,并且会对系统上可用的内容做出不必要的假设(和依赖关系)。

答案 1 :(得分:15)

在C / C ++中,您可以这样做:

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

在Bash,你可以这样做:

rm -r /tmp/*

这将删除/ tmp中的所有内容,但不删除/ tmp本身。

答案 2 :(得分:3)

通过使用通配符*字符,您可以删除具有任何类型扩展名的所有文件。

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

答案 3 :(得分:3)

你可以做到

system("exec find /tmp -mindepth 1 -exec rm {} ';'");

答案 4 :(得分:1)

在C / C ++中,您可以使用(包括隐藏目录):

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

但是如果'rm'或'find'实用程序不可用于sh ?,那么最好去'ftw'和'remove':

#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;
}

答案 5 :(得分:1)

我意识到这是一个非常古老的问题,但是根据Demitri的优秀答案,我创建了一个函数,如果需要,它将递归删除子文件夹中的文件

它还会执行某些错误处理,因为它会传回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;
}

答案 6 :(得分:0)

您可以使用nftw(3)。首先,进行传递以收集要删除的文件路径集。然后在第二遍中使用unlink(对于非目录)和rmdir(2)

答案 7 :(得分:0)

从C ++ 17开始,您可以使用std::filesystem。下面的代码将使用directory_iterator列出目录中的所有文件和子目录,并调用remove_all删除它们:

for alien in aliens_g.sprites():
    alien.blit_a()

请注意,这将在基础OS API错误上引发#include <filesystem> namespace fs = std::filesystem; void delete_dir_content(const fs::path& dir_path) { for (auto& path: fs::directory_iterator(dir_path)) { fs::remove_all(path); } } 异常。您可以通过以下方法避免这种情况:

filesystem_error