上傳單個文件

上傳單個文件.png
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
<form action="http://127.0.0.1:8000/upload" method="post" enctype="multipart/form-data">
頭像:
<input type="file" name="file">
<br>
<input type="submit" value="提交">
<br>
</form>
</body>
</html>
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"log"
)
// gin的Hellowork
func main() {
// 1. 創(chuàng)建路由器
r := gin.Default()
// 2. 綁定路由規(guī)則,執(zhí)行函數(shù)
// gin.Context,封裝了request和respones
r.POST("/upload", func(c *gin.Context) {
// 表單取文件
file, _ := c.FormFile("file")
log.Println(file.Filename)
// 傳到項目錄,名字就用來本身的
c.SaveUploadedFile(file,file.Filename)
// 打印信息
c.String(200,fmt.Sprintf("'%s' upload!",file.Filename))
})
// 3.監(jiān)聽端口,默認(rèn)8080
r.Run(":8000")
}

結(jié)果.png
上傳多個文件

修改的地方
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// gin的Hellowork
func main() {
// 1. 創(chuàng)建路由器
r := gin.Default()
// 限定表單上傳大小 8MB,默認(rèn)為32MB
r.MaxMultipartMemory = 8 << 20
r.POST("/upload", func(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
c.String(http.StatusBadRequest,fmt.Sprintf("get err %s",err.Error()))
}
// 獲取所有圖片
files := form.File["files"]
for _,file := range files {
// 逐個存
if err:=c.SaveUploadedFile(file,file.Filename);err!=nil{
c.String(http.StatusBadRequest,fmt.Sprintf("upload err %s",err.Error()))
return
}
}
c.String(200,fmt.Sprintf("upload ok %d files!"),len(files))
})
// 3.監(jiān)聽端口,默認(rèn)8080
r.Run(":8000")
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
<form action="http://127.0.0.1:8000/upload" method="post" enctype="multipart/form-data">
頭像:
<input type="file" name="files" multiple>
<br>
<input type="submit" value="提交">
<br>
</form>
</body>
</html>
routes group
route group是為了管理一些相同的URL
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
// gin的Hellowork
func main() {
// 1. 創(chuàng)建路由器
r := gin.Default()
// 路由組1,處理GET請求
v1 := r.Group("v1")
// {} 書寫規(guī)范
{
v1.GET("/login",login)
v1.GET("submit",submit)
}
v2 := r.Group("/v2")
{
v2.POST("/login",login)
v2.POST("/submit",submit)
}
// 3.監(jiān)聽端口,默認(rèn)8080
r.Run(":8000")
}
func login(c *gin.Context){
name := c.DefaultQuery("name","jack")
c.String(200,fmt.Sprintf("hello %s \n",name))
}
func submit(c *gin.Context){
name := c.DefaultQuery("name","lily")
c.String(200,fmt.Sprintf("hello %s \n",name))
}
cmd測試
curl http://127.0.0.1:8000/v1/login?name=zhangsan
curl http://127.0.0.1:8000/v1/login?name=zhangsan
路由原理
httproter會將所有路由規(guī)則構(gòu)造一顆前綴樹
例如有root and as cn com
package main
import (
"github.com/gin-gonic/gin"
)
// gin的Hellowork
func main() {
// 1. 創(chuàng)建路由器
r := gin.Default()
// 路由組1,處理GET請求
r.POST("/",xxx)
r.POST("search",xxx)
r.POST("/blog/:post",xxx)
r.POST("/contact",xxx)
r.POST("/about",xxx)
// 3.監(jiān)聽端口,默認(rèn)8080
r.Run(":8000")
}
前綴樹和基數(shù)樹(radix tree)的區(qū)別:
trie又叫前綴樹,是一個多叉樹,廣泛應(yīng)用于字符串搜索,每個樹節(jié)點存儲一個字符,從根節(jié)點到任意一個葉子結(jié)點串起來就是一個字符串;radix tree是優(yōu)化之后的前綴樹,對空間進(jìn)一步壓縮。
下圖左側(cè)是字符串 sex,seed,sleep,son 四個字段串的Trie數(shù)據(jù)結(jié)構(gòu)表示. 可用看到sleep這個字符串需要5個節(jié)點表示. 其實e后面只跟一個p, 也就是只有一個子節(jié)點, 是完全可以和父節(jié)點壓縮合并的. 右側(cè)是優(yōu)化后的數(shù)據(jù)結(jié)構(gòu), 節(jié)省了空間,同時也提高了查詢效率(左邊字符串sleep查詢需要5步, 右邊只需要3步), 這就是radix tree.

樹