libcurl中上传文件的坑-英文操作系统中文路径无法上传返回26错误码

最近在使用libcurl使用表单形式上传本地文件,自己测试的时候都没有问题,但是在测试的电脑上无法上传,返回26错误码,在libcurl的错误码里表示无法读取文件。我把测试上的文件名字改成全英文发现可以上传,由于测试电脑是英文操作系统,所以应该是英文系统中需要上传的文件包含中文路径,这个路径传给libcurl无法找到对应的文件,所以上传失败。

传给liburl的路径是ansi格式的,在网上搜索相关编码问题,得出结论,ansi编码在英文操作系统中表示ascii编码,在中文操作系统中表示gbk编码,在韩文和日文操作系统表示什么大家也就很清楚了。ansi在各个语言的操作系统表示对应各个语言国家规定的文字编码标准。所以,在英文操作系统中使用ansi编码是无法表示中文的,所以在英文操作系统中如果有汉字的unicode字符串转换成ansi就必定会出错,转换后的ansi编码也无法再转换回unicode。

确定问题原因后,开始找解决方案,既然英文操作系统无法使用带中文的ansi,而libcurl上传文件又只能接收ansi编码的路径,所以以我的智商,只能想到两个解决方案:1 传入全英文路径,也就是把文件先复制成英文传过去再上传;2 传入utf8格式路径代替ansi,打开文件时再转成unicode方式打开文件。程序员都知道肯定是第二个效率高,所以决定用第二种方式,修改libcurl中的源代码,把上传过程中对文件路径的操作都改成宽字节方式,即uncode方式。问题解决。其实大神说还可以用libcurl中的read_callback方式,只是我没有深入研究。

贴上修改代码供参考,我们用的是7.68版本的源代码,只修改其中的mine.c文件。

/* Set mime part content from named local file. */
CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
{
  CURLcode result = CURLE_OK;

if(!part)
    return CURLE_BAD_FUNCTION_ARGUMENT;

cleanup_part_content(part);

if(filename) {
    char *base;
    struct_stat sbuf;

if (!stat(filename, &sbuf) && !access(filename, R_OK)) {
        part->data = strdup(filename);
        if (!part->data)
            result = CURLE_OUT_OF_MEMORY;

part->datasize = -1;
        if (!result && S_ISREG(sbuf.st_mode)) {
            part->datasize = filesize(filename, sbuf);
            part->seekfunc = mime_file_seek;
        }

part->readfunc = mime_file_read;
        part->freefunc = mime_file_free;
        part->kind = MIMEKIND_FILE;

/* As a side effect, set the filename to the current file's base name.
           It is possible to withdraw this by explicitly calling
           curl_mime_filename() with a NULL filename argument after the current
           call. */
        base = strippath(filename);
        if (!base)
            result = CURLE_OUT_OF_MEMORY;
        else {
            CURLcode res = curl_mime_filename(part, base);

if (res)
                result = res;
            free(base);
        }
    }
    else {
        //try again with unicode
        struct _stat64i32 file_stat;
        wchar_t* wfilename = get_unicode_from_utf8(filename);
        if (_wstat(wfilename, &file_stat) || _waccess(wfilename, R_OK))
          result = CURLE_READ_ERROR;

part->data = strdup(filename);
        if (!part->data)
            result = CURLE_OUT_OF_MEMORY;

part->datasize = -1;
        if (!result && S_ISREG(file_stat.st_mode)) {
            part->datasize = file_stat.st_size;// filesize(wfilename, sbuf);
            part->seekfunc = mime_file_seek;
        }

part->readfunc = mime_file_read;
        part->freefunc = mime_file_free;
        part->kind = MIMEKIND_FILE;

/* As a side effect, set the filename to the current file's base name.
        It is possible to withdraw this by explicitly calling
        curl_mime_filename() with a NULL filename argument after the current
        call. */
        base = strippath(filename);
        if (!base)
            result = CURLE_OUT_OF_MEMORY;
        else {
            CURLcode res = curl_mime_filename(part, base);

if (res)
                result = res;
            free(base);
        }
        free(wfilename);
    }
  }
  return result;
}

/* Named file callbacks. */
/* Argument is a pointer to the mime part. */
static int mime_open_file(curl_mimepart * part)
{
  /* Open a MIMEKIND_FILE part. */

if(part->fp)
    return 0;
  part->fp = fopen_read(part->data, "rb");
  if (!part->fp) {
      //Open file failed, convert path to unicode from ansi and try to reopen with _wfopen again
      wchar_t *  unicode = get_unicode_from_utf8(part->data);
      part->fp = _wfopen(unicode, L"rb");
      free(unicode);
  }
  return part->fp? 0: -1;
}

libcurl中上传文件的坑-英文操作系统中文路径无法上传返回26错误码相关推荐

  1. bootstrap-fileinput上传文件的插件使用总结----编辑已成功上传过的图片

    http://plugins.krajee.com/file-plugin-methods-demo 具体操作 http://plugins.krajee.com/file-preview-manag ...

  2. vue上传文件到php,vue+axios+php如何实现上传文件功能?,formdata上传文件附加参数...

    vue+axios+php如何实现上传文件功能?Vue Axios PHP如何实现上传文件的功能?, 推荐:<PHP视频教程> 当我们提交表单时,我们经常会遇到一些表单提交要求.vue的a ...

  3. PHP上传文件超过了最大文件大小限制导致无法上传成功

    最近的研究<HeadFirst PHP & MySQL>第一本书5章"使用存储在文件中的数据",难道当一个文件上传应用程序,发生了错误.即,文件不能成功上传.这 ...

  4. javaweb上传文件_javaWeb中,如何通过CommonsFileUpload组件上传文件

    大家好,欢迎来到雄雄的小课堂,今天给大家分享的是<javaWeb中,如何通过Commons-FileUpload组件上传文件> 前言:文件上传大家都不陌生,在这个互联网飞速发展的时代,共享 ...

  5. php 上传文件 重命名_如何用PHP给上传的文件改名

    用PHP给上传的文件改名的方法:首先新建一个html文件,并创建form表单:然后新建Php文件用于接收form表单传递过来的文件数据,并设置文件的编码为utf8:接着创建上传文件保存的目录变量[$s ...

  6. ssm上传文件进度条_SSM框架+Plupload实现分块上传大文件示例

    关于Plupload的介绍,相信它的官网http://www.plupload.com/已经给得很详细了.Plupload的上传原理简单点说,就是将用户选中的文件(可多个)分隔成一个个小块,依次向服务 ...

  7. 怎么上传文件到kk服务器,VS Code 关于SFTP上传文件到多服务器的配置

    工欲善其事,必先利其器! 刚学前端的时候一直用的DW来编写代码,其功能非常强大,但在Linux下不能用,所以就转VS Code了. 但是刚开始使用VS Code的时候,很多DW上的功能需要自己安装扩展 ...

  8. java form 上传文件_JAVA入门[16]-form表单,上传文件

    一.如何传递参数 @RequestMapping("/detail") public String detail(@RequestParam("id") int ...

  9. git怎么上传文件到别人的仓库_Git将本地代码上传至远程仓库

    之前做项目接触的版本管理工具都是用的SVN.但是目前行业中比较流行的是Git.更有民间说法讲不会Git的话都找不到工作.所以最近趁业余时间来学习了一下怎么使用Git(感觉SVN真的挺好用的.嘿嘿嘿). ...

最新文章

  1. Linux开启FTP(vsftpd)服务
  2. PAT甲级 -- 1148 Werewolf - Simple Version (20 分)
  3. 简单理解bash和常规操作
  4. [置顶] export命令-linux
  5. canvas笔记-文字渲染
  6. C语言 socket
  7. mysql怎么获得权限_mysql怎么给用户加权限
  8. HBase常用操作备忘
  9. ConvMF论文解读
  10. ubuntu下从软件中心安装软件时的软件缓存目录
  11. 一些值得学习的Unity教程
  12. 苹果cmsV10资源采集插件
  13. Roboware (ROS IDE)字体设置
  14. 一起学英语 | 用JavaScript实现数字阶乘的三种方法
  15. UTF-8转码GBK
  16. 题目:L2-029 特立独行的幸福 (25 分)
  17. 摩斯密码php,普及一下LOL中的摩斯密码 绝对的干货
  18. python爬取豆瓣影评
  19. 一个毕业6年的程序员工作经历和成长感悟(终)
  20. C语言用户注册登录管理系统_JavaFX+SpringBoot+验证码功能的小型薪酬管理系统

热门文章

  1. 一文读懂TDengine的三种查询功能
  2. orical 数据库 搜索语句
  3. ESP8266开发之旅 网络篇⑭ web配网
  4. CloudFront-转发到其他域名
  5. 程序设计基础(CC++) 戴波、张东祥 第六章 函数 编程作业
  6. Unix Sed Tutorial 2 : Delete File Lines Using Address and Patterns
  7. APP运营推广策略的基本要点
  8. grimvalor哪里有中文_Grimvalor中文版
  9. 都是 Thumbs.db 惹的祸
  10. arm反汇编 之数组