dzc0426 发表于 2021-11-23 15:49:00

FileX删除整个文件夹代码

本帖最后由 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);
}


dzc0426 发表于 2021-11-23 15:50:44

特别是删完文件夹后需要重新调用fx_directory_first_full_entry_find,有点恶心

eric2013 发表于 2021-11-24 09:27:40

谢谢楼主分享

HenryLAU 发表于 2023-5-31 12:01:57

感谢楼主分享,有个问题不知道算不算,进入接口后fx_directory_default_set改成当前文件夹为默认路径,那么这个文件夹下的文件删除时就不应该再组成完整路径了,直接使用文件名就行了吧,即删除文件那里应该使用entry_name而不是path

eric2013 发表于 2023-6-1 00:59:23

HenryLAU 发表于 2023-5-31 12:01
感谢楼主分享,有个问题不知道算不算,进入接口后fx_directory_default_set改成当前文件夹为默认路径,那么 ...

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

HenryLAU 发表于 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文件夹。正常默认路径是根目录,没有改过。

HenryLAU 发表于 2023-7-14 13:45:28

感谢楼主分享,不过使用测试确实无法通过,如下分享使用动态内存的方式防止栈溢出。无需动态内存也可使用局部变量。整体与楼主一致,更改后测试通过。 PS:FX版本6.2.0
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 = '/';
      defaultPath = '\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)
      {
            break;
      }

      if ('.' == entry_name)
      {
            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;
}
页: [1]
查看完整版本: FileX删除整个文件夹代码