硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1671|回复: 6
收起左侧

[FileX] FileX删除整个文件夹代码

[复制链接]

1

主题

16

回帖

19

积分

新手上路

积分
19
发表于 2021-11-23 15:49:00 | 显示全部楼层 |阅读模式
本帖最后由 dzc0426 于 2021-11-23 15:52 编辑

FileX删除整个文件夹遇到一些坑,分享下最终可用代码,测试可用,注意任务栈别爆了。

UINT FileXDeleteDirectory(FX_MEDIA *media_ptr, CHAR *dir) {
    UINT status = fx_directory_delete(media_ptr, dir);
    if( FX_NOT_FOUND == status || FX_SUCCESS == status) {//不存在也可以认为删除成功
        return FX_SUCCESS;
    }

    if( FX_DIR_NOT_EMPTY != status ) {
        return status;
    }

    //到这里说明文件夹存在并且非空
    CHAR defaultPath[FX_MAXIMUM_PATH] = {0};
    status = fx_directory_default_get_copy(media_ptr, defaultPath, sizeof(defaultPath));
    if (status != FX_SUCCESS) {
        return status;
    }

    if( 0 == strnlen(defaultPath, sizeof(defaultPath)) ) {
        defaultPath[0] = '/';
        defaultPath[1] = '\0';
    }

    status = fx_directory_default_set(media_ptr, dir);
    if (status != FX_SUCCESS) {
        return status;
    }

    UINT attributes = 0;
    ULONG size      = 0;
    UINT year       = 0;
    UINT month      = 0;
    UINT day        = 0;
    UINT hour       = 0;
    UINT minute     = 0;
    UINT second     = 0;
    CHAR entry_name[FX_MAX_LONG_NAME_LEN] = {0};

    bool firstFlag = true;
    UINT (*findEntry)(FX_MEDIA *, CHAR *, UINT *, ULONG *, UINT *, UINT *, UINT *, UINT *, UINT *, UINT *) = fx_directory_first_full_entry_find;
    for(;;) {
        if( !firstFlag ) {
            findEntry = fx_directory_next_full_entry_find;
        }

        firstFlag = false;
        status = findEntry( media_ptr,
                            entry_name,
                            &attributes,
                            &size,
                            &year, &month, &day,
                            &hour, &minute, &second);

        if ( FX_SUCCESS != status || !entry_name[0] ) {
            break;
        }

        if ( '.' == entry_name[0] ) {
            continue;
        }

        CHAR path[FX_MAXIMUM_PATH] = {0};
        if(snprintf(path, sizeof(path), "%s/%s", dir, entry_name) < 0 ) {
            return fx_directory_default_set(media_ptr, defaultPath);
        }

        if (attributes & FX_DIRECTORY) {
            status = FileXDeleteDirectory(media_ptr, path);
            if( FX_SUCCESS != status ) {
                return fx_directory_default_set(media_ptr, defaultPath);
            }
            findEntry = fx_directory_first_full_entry_find;
            firstFlag = true;//如果删除完了文件夹,需要重新从头扫描。。。
        }
        else {
            status = fx_file_delete(media_ptr, path);
            if( FX_SUCCESS != status ) {
                return fx_directory_default_set(media_ptr, defaultPath);
            }
        }
    }

    fx_directory_delete(media_ptr, dir);
    return fx_directory_default_set(media_ptr, defaultPath);
}


回复

使用道具 举报

1

主题

16

回帖

19

积分

新手上路

积分
19
 楼主| 发表于 2021-11-23 15:50:44 | 显示全部楼层
特别是删完文件夹后需要重新调用fx_directory_first_full_entry_find,有点恶心
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106534
QQ
发表于 2021-11-24 09:27:40 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
发表于 2023-5-31 12:01:57 | 显示全部楼层
感谢楼主分享,有个问题不知道算不算,进入接口后fx_directory_default_set改成当前文件夹为默认路径,那么这个文件夹下的文件删除时就不应该再组成完整路径了,直接使用文件名就行了吧,即删除文件那里应该使用entry_name而不是path
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106534
QQ
发表于 2023-6-1 00:59:23 | 显示全部楼层
HenryLAU 发表于 2023-5-31 12:01
感谢楼主分享,有个问题不知道算不算,进入接口后fx_directory_default_set改成当前文件夹为默认路径,那么 ...

你那边测试,使用fx_directory_default_set后是完成路径还是仅文件名即可
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
发表于 2023-6-1 08:56:28 | 显示全部楼层
eric2013 发表于 2023-6-1 00:59
你那边测试,使用fx_directory_default_set后是完成路径还是仅文件名即可

fx_directory_default_set写的参数 是dir,我这边调用时dir时完整路径如0/1,表示删除0文件夹里面的1文件夹。正常默认路径是根目录,没有改过。
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
发表于 2023-7-14 13:45:28 | 显示全部楼层
感谢楼主分享,不过使用测试确实无法通过,如下分享使用动态内存的方式防止栈溢出。无需动态内存也可使用局部变量。整体与楼主一致,更改后测试通过。 PS:FX版本6.2.0
[C] 纯文本查看 复制代码
static UINT FileXDeleteDirectory(FX_MEDIA *media_ptr, CHAR *dir)
{
    UINT status = fx_directory_delete(media_ptr, dir);
    if (FX_NOT_FOUND == status || FX_SUCCESS == status)
    {
        return FX_SUCCESS; // 不存在也可以认为删除成功
    }
    FS_DBG_INFO("DEL DIR");
    if (FX_DIR_NOT_EMPTY != status)
    {
        return status;
    }

    // 到这里说明文件夹存在并且非空
    CHAR *defaultPath = (CHAR *)FS_MALLOC(FX_MAXIMUM_PATH);
    CHAR *entry_name = (CHAR *)FS_MALLOC(FX_MAX_LONG_NAME_LEN);

    if (defaultPath == NULL || entry_name == NULL)
    {
        return FX_NO_MORE_SPACE;
    }
    memset(defaultPath, 0x00, FX_MAXIMUM_PATH);
    status = fx_directory_default_get_copy(media_ptr, defaultPath, FX_MAXIMUM_PATH);
    if (status != FX_SUCCESS)
    {
        goto ERREXIT;
    }

    if (0 == strlen(defaultPath))
    {
        defaultPath[0] = '/';
        defaultPath[1] = '\0';
    }

    status = fx_directory_default_set(media_ptr, dir);
    if (status != FX_SUCCESS)
    {
        goto ERREXIT;
    }

    UINT attributes = 0;
    ULONG size = 0;
    UINT year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;


    bool firstFlag = true;
    UINT(*findEntry)
    (FX_MEDIA *, CHAR *, UINT *, ULONG *, UINT *, UINT *, UINT *, UINT *, UINT *, UINT *) = fx_directory_first_full_entry_find;

    for (;;)
    {
        if (!firstFlag)
        {
            findEntry = fx_directory_next_full_entry_find;
        }

        firstFlag = false;
        status = findEntry(media_ptr, entry_name, &attributes, &size,
                           &year, &month, &day, &hour, &minute, &second);

        if (FX_SUCCESS != status || !entry_name[0])
        {
            break;
        }

        if ('.' == entry_name[0])
        {
            continue;
        }

        if (attributes & FX_DIRECTORY)
        {
            findEntry = fx_directory_first_full_entry_find;
            status = FileXDeleteDirectory(media_ptr, entry_name);
            fx_directory_default_set(media_ptr, defaultPath); // 还原要删除的路径为默认路径 不能用相对路径还原
            if (FX_SUCCESS != status)
            {
                goto ERREXIT;
            }
            status = fx_directory_default_set(media_ptr, dir); // 还原要删除的路径为默认路径
            if (status != FX_SUCCESS)
            {
                FS_DBG_ERR("def path:%s/%s err:%d", defaultPath, dir, status);
            }
            firstFlag = true; // 如果删除完了文件夹,需要重新从头扫描。。。
        }
        else
        {
            status = fx_file_delete(media_ptr, entry_name);
            if (FX_SUCCESS != status)
            {
                FS_DBG_ERR("%s del err", entry_name);
                fx_directory_default_set(media_ptr, defaultPath);
                goto ERREXIT;
            }
            FS_DBG_INFO("file %s delete success", entry_name);
        }
    }
    status = fx_directory_default_set(media_ptr, defaultPath); // 恢复默认设置,为了删除该文件夹
    if (status != FX_SUCCESS)
    {
        FS_DBG_ERR("org def dir %s err:%d", defaultPath, status);
    }

    status = fx_directory_delete(media_ptr, dir);
    if (FX_SUCCESS != status)
    {
        FS_DBG_ERR("%s del err:%d", dir, status);
    }
    else
    {
        FS_DBG_INFO("dir %s delete success", dir);
    }

ERREXIT:
    FS_FREE(defaultPath);
    FS_FREE(entry_name);
    return status;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-24 03:04 , Processed in 0.180541 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表