先带大家了解相关需要了解的包及其相关操作
strconv 包 : https://www.cnblogs.com/golove/p/3262925.html
io/ioutil 包: https://www.cnblogs.com/golove/p/3278444.html
Os 文件操作包: https://studygolang.com/articles/11101?fr=sidebar
path/filepath 文件目录操作包: https://blog.csdn.net/wangshubo1989/article/details/74330674
是不是有个疑惑, 为什么要学习这么些个包。用到的时候再找不就可以了吗? 其实,其上说的也是对的, 但不可忽略的一个问题便是,在初学期间, 我们必须在使用的过程中了解并且熟悉的操作这些方法。 同时利用自己学习的包参考源码,便能慢慢的理解 go 中的一些数据结构和参数的使用办法。
go 的源码的注释非常详细, 无奈, 我的英语水平太差, 只能借助翻译, 同时借助翻译和中文释义包, 渐渐的也能慢慢的读懂,这也是一个进步吧
推荐大家参考中文包的解释同时进行阅读源码注释
以下是如题的代码
uploadOne.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
文件:<input type="file" name="file" value=""><br>
<input type="hidden" name="token" value="{{.}}">
<input type="text" name="name" id="">
<input type="submit" value="提交">
</form>
</body>
</html>
uploadMore.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/uploadMore" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="" placeholder="文件名称">
<input type="file" name="file" id="">
<input type="file" name="file" id="">
<input type="file" name="file" id="">
<input type="submit" value="提交">
</form>
</body>
</html>
main.go
package main
import (
"crypto/md5"
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
"strconv"
"time"
)
// 参考 : https://www.cnblogs.com/jkko123/p/7001673.html
func uploadOne(w http.ResponseWriter, r *http.Request) {
fmt.Println("methods:", r.Method)
if r.Method == "GET" {
// 得到一个当前的unix时间戳
crutime := time.Now().Unix()
// 创建一个md5值
h := md5.New()
// strconv.FormatInt
// 将整数转换为字符串形式。base 表示转换进制,取值在 2 到 36 之间。
// 结果中大于 10 的数字用小写字母 a - z 表示。
// ----
// 得到的字符串写入到h中,如果 h 已经实现了WriteString则直接返回 h , md5 未实现
io.WriteString(h, strconv.FormatInt(crutime, 10))
// h.Sum 的意思为 h是一个md5值, 通过h.sum 得到一个hash散列值
token := fmt.Sprintf("%x", h.Sum(nil))
// 解析模板引擎
t, _ := template.ParseFiles("uploadOne.html")
// 输出模板和参数token
t.Execute(w, token)
} else {
// ParseMultipartForm将请求的主体作为multipart/form-data解析。
// 请求的整个主体都会被解析,得到的文件记录最多maxMemery字节保存在内存,其余部分保存在硬盘的temp文件里
// 32 << 20 表示 转化为二进制并且向左边偏移20位
r.ParseMultipartForm(10 << 20) // 10 mb
file, handler, err := r.FormFile("file")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
fmt.Fprintf(w, "%v", handler.Header)
os.Mkdir("./upload", os.ModePerm)
f, err := os.OpenFile("./upload/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
// 将file文件流写入到f中,f已经在上面创建成了一个文件, 相当于,改变如上的f文件信息为当前的上传的文件信息
io.Copy(f, file)
// application/x-www-form-urlencoded 的时候 不需要使用 r.ParseForm()
r.ParseForm()
token := r.Form.Get("token")
if token != "" {
fmt.Println("echo :%s", token)
} else {
fmt.Println("token验证失败")
}
//
//fmt.Println("username length:", len(r.Form["username"][0]))
//fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) // 输出到服务器端
//fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password")))
template.HTMLEscape(w, []byte(handler.Filename)) // 输出到客户端
}
}
func uploadMore(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
r. ParseMultipartForm(30 << 20)
// 多图获取图片信息
files := r.MultipartForm.File["file"]
len := len(files)
for i :=0; i < len; i++{
file, err := files[i].Open()
defer file.Close()
checkErr(err)
os.Mkdir("./upload", os.ModePerm)
cur, err := os.Create("./upload/" + files[i].Filename)
defer cur.Close()
io.Copy(cur, file)
r.ParseForm()
fmt.Println("name", template.HTMLEscapeString(r.Form.Get("name")) )
template.HTMLEscape(w, []byte(r.Form.Get("name")))
}
} else {
t, _ := template.ParseFiles("./uploadMore.html")
t.Execute(w, nil)
}
}
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
http.HandleFunc("/upload", uploadOne)
http.HandleFunc("/uploadMore", uploadMore)
http.ListenAndServe(":8081", nil)
}
本文由 邓尘锋 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jun 27, 2019 at 11:10 pm