Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何删除文件夹中的所有文件,但不使用NIX标准库删除文件夹?_C++_C_Linux_Unix - Fatal编程技术网

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

C++ 如何删除文件夹中的所有文件,但不使用NIX标准库删除文件夹?,c++,c,linux,unix,C++,C,Linux,Unix,我正在尝试创建一个删除/tmp文件夹内容的程序,我在linux上使用C/C++ system("exec rm -r /tmp") 删除文件夹中的所有内容,但它也删除了我不想要的文件夹 是否有任何方法可以通过某种bash脚本来实现这一点,该脚本称为viasystem();或者有没有一种直接的方法可以在C/C++中实现这一点 我的问题和这个差不多,但我不在OSX上 使用通配符*可以删除所有扩展名为任何类型的文件 系统(“exec rm-r/tmp/*”在C/C++中,您可以执行以下操作: sys

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

system("exec rm -r /tmp")
删除文件夹中的所有内容,但它也删除了我不想要的文件夹

是否有任何方法可以通过某种bash脚本来实现这一点,该脚本称为via
system()
;或者有没有一种直接的方法可以在C/C++中实现这一点


我的问题和这个差不多,但我不在OSX上

使用通配符
*
可以删除所有扩展名为任何类型的文件


系统(“exec rm-r/tmp/*”

在C/C++中,您可以执行以下操作:

system("exec rm -r /tmp/*")
rm -r /tmp/*
在Bash中,您可以执行以下操作:

system("exec rm -r /tmp/*")
rm -r /tmp/*
这将删除/tmp中的所有内容,但不会删除/tmp本身。

您可以这样做

system("exec find /tmp -mindepth 1 -exec rm {} ';'");
#包括
#包括
int main()
{
//这些是在“dirent”标题中定义的数据类型
DIR*offolder=opendir(“path/of/folder”);
struct dirent*下一个_文件;
char文件路径[256];
while((next_file=readdir(theFolder))!=NULL)
{
//为文件夹中的每个文件生成路径
sprintf(文件路径、%s/%s、/path/of/folder)、下一个文件->文件名);
删除(文件路径);
}
closedir(offolder);
返回0;
}
您不想通过
system()
或类似的方式生成一个新的shell-做一些非常简单的事情会有很大的开销,并且会对系统上可用的内容做出不必要的假设(和依赖项)。

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

但是,如果sh无法使用“rm”或“find”实用程序,则最好使用“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;
}
\define\XOPEN\u源代码500
#包括
静态int remove_cb(const char*fpath,const struct stat*sb,int typeFlag,struct FTW*ftwbuf)
{
如果(ftwbuf->level)
移除(fpath);
返回0;
}
内部主(空)
{
nftw(“./方向”,移除cb,10,FTW\U深度);
返回0;
}

我意识到这是一个非常古老的问题,但在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;
}
#包括
#包括
#包括
#定义成功状态0
/**
*检查特定目录是否存在
*@param dir_path要检查的路径
*@return如果路径存在
*/
bool dirExists(std::string dir\u path)
{
结构统计某人;
if(stat(dir_path.c_str(),&sb)=0和&S_ISDIR(sb.st_模式))
返回true;
其他的
返回false;
}
/**
*删除文件夹中的所有文件(但不删除文件夹本身)。选择性地
*当recursive为true时,这可以遍历子文件夹并删除所有内容
*@param dirpath要删除内容的目录(可以是完整目录或
*相对路径)
*@param recursive true=删除所有子文件夹中的所有文件/文件夹
*false=仅删除顶级目录中的文件
*@return SUCCESS\u成功统计
*errno失败时,值可以来自unlink或rmdir
*@注意:这不会删除命名目录,只删除其内容
*/
int DeleteFilesInDirectory(std::string dirpath,bool recursive)
{
if(dirpath.empty())
返回成功状态;
DIR*offolder=opendir(dirpath.c_str());
struct dirent*下一个_文件;
char文件路径[1024];
国际检索;
if(offolder==NULL)
返回errno;
while((next_file=readdir(theFolder))!=NULL)
{
//为文件夹中的每个文件生成路径
sprintf(文件路径,“%s/%s”,dirpath.c_str(),下一个文件->d_名称);
//我们不想处理指向“this”或“parent”目录的指针
如果((strcmp(下一个\u文件->d\u名称,“…”)==0)||
(strcmp(下一个\u文件->d\u名称,“.”=0))
{
继续;
}
//dirExists将检查“文件路径”是否为目录
if(dirExists(filepath))
{
if(!递归)
//如果我们不是递归删除子文件夹中的,请跳过此目录
继续;
ret_val=DeleteFilesInDirectory(文件路径,递归);
如果(返回值!=成功统计)
{
closedir(offolder);
返回返回值;
}
}
ret_val=remove(文件路径);
//当i文件夹在中为空或是悬空链接时,将发生eNONT
//在这种情况下,我们会说它是成功的,因为文件已经不存在了
if(ret_val!=SUCCESS_STAT&&ret_val!=enoint)
{
closedir(offolder);
返回返回值;
}
}
closedir(offolder);
返回成功状态;
}

您可以使用。首先,通过收集要删除的文件路径集。然后使用
取消链接
(对于非目录)并在第二遍中从C++17开始使用。下面的代码将用于列出目录中的所有文件和子目录,并调用以删除它们:

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

rm-r/tmp/*
将删除文件夹的内容。如果您想在未来投资,可以使用
boost::filesystem
迭代并删除每个文件夹。@AusCBloke:Uhm。。。这将删除文件夹中所有可见的文件(即,
*
扩展到的文件),但不会删除任何以
@DavidRodríguez dribeas开头的文件。噢,是的,这是一个很好的观点。@DavidRodríguez dribeas:另一方面,删除/tmp的内容会有什么害处吗?嗯。。。这将删除文件夹中所有可见的文件(即扩展到的文件),但不会删除任何以开头的文件。从C调用“system”都是不安全的@杰克:我同意。但是(因为你投了否决票)请记住,OP确实问过,“……有没有办法通过某种bash脚本来实现这一点,c
void delete_dir_content(const fs::path& dir_path) {
    for (auto& path: fs::directory_iterator(dir_path)) {
        std::error_code err;
        std::uintmax_t n = fs::remove_all(path, err);
        if (static_cast<std::uintmax_t>(-1) == n) {
            std::cout << "Failed to remove_all(" << path << ") with error: " << err.message() << std::endl;
        }
    }
}