文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

GO实现文件上传操作

2024-04-02 19:55

关注

本文实例为大家分享了GO实现文件上传操作的具体代码,供大家参考,具体内容如下

由于需求中有文件上传这一个需求,在这里我们就学习一下go语言如何上传文件。本文主要通过表单的方式进行文件上传操作。主要有以下三步:

1、表单操作

要使表单能够上传文件,首先第一步就要添加form的enctype属性进去,enctype属性有如下三种情况:

application/x-www-form-urlencoded   表示在发送前编码所有字符(默认)
multipart/form-data      不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain      空格转换为 "+" 加号,但不对特殊字符编码。

所以可以创建如下上传表单:

<html>
<head>
    <title>上传文件</title>
</head>
<body>
<form enctype="multipart/form-data" action="/upload" method="post">
  <input type="file" name="uploadfile" />
  <input type="hidden" name="token" value="{{.}}"/>
  <input type="submit" value="upload" />
</form>
</body>
</html>

2、服务端操作

在服务端只需要添加一个handlerFunc并完善相关功能即可:

// 处理/upload 逻辑
func upload(w http.ResponseWriter, r *http.Request) {
    //获取请求的方法
    fmt.Println("method:", r.Method)
    //GET的处理操作
    if r.Method == "GET" {
        crutime := time.Now().Unix()
        h := md5.New()
        io.WriteString(h, strconv.FormatInt(crutime, 10))
        token := fmt.Sprintf("%x", h.Sum(nil))

        t, _ := template.ParseFiles("upload.gtpl")
        t.Execute(w, token)
    } else {
        //设置内存大小
        r.ParseMultipartForm(32 << 20)
        //获取上传文件
        file, handler, err := r.FormFile("uploadfile")
        if err != nil {
            fmt.Println(err)
            return
        }
        defer file.Close()
        fmt.Fprintf(w, "%v", handler.Header)
        //创建上传目录
        os.Mkdir("./test", os.ModePerm)
        //创建上传文件
        f, err := os.Create("./test/" + handler.Filename)
        //f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) // 此处假设当前目录下已存在test目录
        if err != nil {
            fmt.Println(err)
            return
        }
        defer f.Close()
        io.Copy(f, file)
    }
}

main()函数中记得添加http.HandleFunc("/upload", upload)即可。

通过http://127.0.0.1:9999/upload来测试文件上传。 截图

选择文件之后就会在当前目录下的test文件夹中成功上传文件。

3、流程解析

通过上面的代码可以看到,处理文件上传我们需要调用r.ParseMultipartForm,里面的参数表示maxMemory,调用ParseMultipartForm之后,上传的文件存储在maxMemory大小的内存里面,如果文件大小超过了maxMemory,那么剩下的部分将存储在系统的临时文件中。我们可以通过r.FormFile获取上面的文件句柄,然后实例中使用了io.Copy来存储文件。我们可以尝试使用看一下使用的相关原函数:

ParseMultipartForm函数如下:

func (r *Request) ParseMultipartForm(maxMemory int64) error {
    if r.MultipartForm == multipartByReader {
        return errors.New("http: multipart handled by MultipartReader")
    }
    if r.Form == nil {
        err := r.ParseForm()
        if err != nil {
            return err
        }
    }
    if r.MultipartForm != nil {
        return nil
    }

    mr, err := r.multipartReader(false)
    if err != nil {
        return err
    }

    f, err := mr.ReadForm(maxMemory)
    if err != nil {
        return err
    }

    if r.PostForm == nil {
        r.PostForm = make(url.Values)
    }
    for k, v := range f.Value {
        r.Form[k] = append(r.Form[k], v...)
        // r.PostForm should also be populated. See Issue 9305.
        r.PostForm[k] = append(r.PostForm[k], v...)
    }

    r.MultipartForm = f

    return nil
}

FormFile函数如下:

func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
    if r.MultipartForm == multipartByReader {
        return nil, nil, errors.New("http: multipart handled by MultipartReader")
    }
    if r.MultipartForm == nil {
        err := r.ParseMultipartForm(defaultMaxMemory)
        if err != nil {
            return nil, nil, err
        }
    }
    if r.MultipartForm != nil && r.MultipartForm.File != nil {
        if fhs := r.MultipartForm.File[key]; len(fhs) > 0 {
            f, err := fhs[0].Open()
            return f, fhs[0], err
        }
    }
    return nil, nil, ErrMissingFile
}

文件handlermultipart.FileHeader里面的结构体如下

// A FileHeader describes a file part of a multipart request.
type FileHeader struct {
    Filename string
    Header   textproto.MIMEHeader
    Size     int64

    content []byte
    tmpfile string
}

4、成功结果

浏览器端显示如下消息。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯