GO实现文件上传操作

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

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

  • 表单中增加enctype属性
  • 服务端调用r.ParseMultipartForm,把上传的文件存储在内存和临时文件中
  • 使用r.FormFile获取文件句柄,然后对文件进行存储等处理。

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、成功结果

浏览器端显示如下消息。

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

(0)

相关推荐

  • GO语言实现文件上传代码分享

    功能很简单,代码也很简洁,这里就不多废话了. 复制代码 代码如下: package main import (     "fmt"     "io"     "net/http"     "os" ) const (     upload_path string = "./upload/" ) func helloHandle(w http.ResponseWriter, r *http.Request)

  • Django实现文件上传下载功能

    项目介绍 最近学习django,通过文件上传下载这个小项目,总结下常用的知识点. 做这个案例我有以下需求: 1.要支持一次上传多个文件 2.支持上传后记录上传的数据以及列表展示 3.支持下载和删除文件记录 效果展示 数据库记录 开发步骤 创建项目: django-admin startproject file_upload cd file_upload python manage.py startapp uploader 目录结构: 0.settings.py LANGUAGE_CODE = '

  • Go Gin实现文件上传下载的示例代码

    Go Gin 实现文件的上传下载流读取 文件上传 router router.POST("/resources/common/upload", service.UploadResource) service type: POST data:{ "saveDir":"保存的路径", "fileName":"文件名称不带后缀" } // 上传文件 func UploadResource(c *gin.Conte

  • golang实现的文件上传下载小工具

    前言 虽然现在文件上传下载工具多如牛毛,比如http.ftp.sftp.scp等方案都可以用于文件传输,但都是需要安装服务器甚至客户端. 有一种场景是我只需要临时上传或下载一个文件,完了就不用服务器运行了,如果使用那些文件传输工具,不光安装麻烦,开启关闭也恼火额. 因此才想搞小工具,不过Python爱好者可以用python -m http.server 8080 --bind 192.168.1.100开启文件服务器,对我来说还是麻烦. 已经上传到[Github],随意鉴赏. 源码鉴赏 模拟一个

  • golang语言实现的文件上传与文件下载功能示例

    本文实例讲述了golang实现的文件上传与文件下载功能.分享给大家供大家参考,具体如下: upload.go 复制代码 代码如下: package common import (  "io/ioutil"  "os"  "path"  "github.com/gin-gonic/gin"  "googo.co/goo"  "googo.co/utils" ) const (  UPLOA

  • Golang实现http文件上传小功能的案例

    看代码吧~ package main import ( "fmt" "io" "net/http" "os" ) func main() { http.HandleFunc("/", index) http.HandleFunc("/upload", upload) http.ListenAndServe(":1789", nil) } func upload(w h

  • 用go gin server来做文件上传服务

    之前已经go get安装了gin, 现在来玩下用go gin server作图片上传服务, 代码目录如下: taoge:~/test_gin$ tree . |-- public |-- template | `-- select_file.html `-- test_gin_server.go 2 directories, 2 files taoge:~/test_gin$ test_gin_server.go内容: package main import ( "fmt" "

  • 基于Ajaxupload的多文件上传操作

    废话不多说了,直接给大家贴代码了,具体代码如下所示: <pre name="code" class="php"><?php $ele = $_GET['ele']; $file = $_FILES['thumb_'.$ele]; $pathinfo = pathinfo($file['name']); $filedir = 'uploads/' . date('Y'); if (!is_dir($filedir)) { mkdir($filedir

  • PHP文件上传操作实例详解

    本文实例分析了PHP文件上传操作.分享给大家供大家参考,具体如下: 文件上传 发生在浏览器向服务器发出的请求中. 文件,对于浏览器来讲,就是表单中的一个特殊类型的数据而已. 浏览器表单中的数据,两种类型: 字符串类型(字节流编码) 文件类型(二进制编码),文件是表单数据中一部分 服务器角度: 在接受浏览器请求时,处理好表单内的数据.根据数据类型不同使用不同处理方法: 字符串类型,存储在$_POST变量中(内存) 文件型数据,存储在上传临时目录中 表单提交时,浏览器会默认的行为: 表单内的的内容都

  • jquery插件ajaxupload实现文件上传操作

    本文实例讲述了jquery插件ajaxupload实现文件上传操作代码.分享给大家供大家参考.具体如下: 运行效果截图如下: 图1 文件上传前 图2 文件上传后 具体代码如下: 1.创建页面并编写HTML 上传文档: <div class="uploadFile"> <span id="doc"><input type="text" disabled="disabled" /></sp

  • servlet3文件上传操作

    在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileupload组件,在Servlet3.0中提供了对文件上传的原生支持,我们不需要借助任何第三方上传组件,直接使用Servlet3.0提供的API就能够实现文件上传功能了. 一.使用Servlet3.0提供的API实现文件上传 1.1.编写上传页面 <%@ page language="java" pageEncoding="UTF-8"%

  • Python基于FTP模块实现ftp文件上传操作示例

    本文实例讲述了Python基于FTP模块实现ftp文件上传操作.分享给大家供大家参考,具体如下: #!/usr/bin/python #-*- coding:utf-8 -*- from ftplib import FTP #加载ftp模块 ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp.connect("IP","port") #连接的ftp sever和端口 ftp.login("us

  • TP3.2.3框架文件上传操作实例详解

    本文实例讲述了TP3.2.3框架文件上传操作.分享给大家供大家参考,具体如下: 上传表单 在ThinkPHP中使用上传功能无需进行特别处理.例如,下面是一个带有附件上传的表单提交: <form action="__URL__/upload" enctype="multipart/form-data" method="post" > <input type="text" name="name"

  • PHP实现文件上传操作和封装

    本文实例为大家分享了PHP实现文件上传操作和封装的具体代码,供大家参考,具体内容如下 PHP文件上传主要两个步骤: 1.首先前端html写好文件表单上传网页 2.在前端点提交时,web服务器php脚本通过超全局变量$_FILES和一个move_uploaded_file函数搞定 前端html如下: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>文件上传&

  • selenium+python实现文件上传操作的方法实例

    前言 selenium处理文件上传大致会有两种情况,一种是文件上传使用的是input标签元素,即<input type="file">,那么对这个input标签元素使用sendkeys方法输入文件的路径就可以完成上传,另一种是调用windows系统完成文件上传,即文件上传会弹出windows弹窗,此时则需要借助Autoit这样一个小工具结合selenium完成. 方法如下 1.文件上传使用的是input标签元素,selenium+python代码示例参考如下: import

  • GO实现文件上传操作

    本文实例为大家分享了GO实现文件上传操作的具体代码,供大家参考,具体内容如下 由于需求中有文件上传这一个需求,在这里我们就学习一下go语言如何上传文件.本文主要通过表单的方式进行文件上传操作.主要有以下三步: 表单中增加enctype属性 服务端调用r.ParseMultipartForm,把上传的文件存储在内存和临时文件中 使用r.FormFile获取文件句柄,然后对文件进行存储等处理. 1.表单操作 要使表单能够上传文件,首先第一步就要添加form的enctype属性进去,enctype属性

  • 详解SpringMVC中的日期处理和文件上传操作

    目录 日期格式处理 日期格式处理 创建自定义日期转换器 配置自定义转换器 文件上传下载 文件上传 文件下载 日期格式处理 在控制器中使用对象接收数据 前端: <form action="test/add" method="post"> <p>图书名称:<input type="text" name="bookName"/></p> <p>图书作者:<input

随机推荐