最近再写一个文件上传的功能,鉴于自己对go 语言的经验不够,所以写的东西可能很一般,还请大家多多指教
<br/>话不多说,直接上代码
```
package main
import (
"fmt"
"html/template"
"io"
"sync"
"log"
"net/http"
"os"
"time"
)
type Buffer struct {
bit []byte
blen int
}
var bufpool *sync.Pool
func initbt() {
bufpool = &sync.Pool{}
bufpool.New = func() interface{} {
return Buffer{
bit: make([]byte, 64*1024),
blen: 0,
}
}
}
func Copy(dst1 io.Writer, src io.Reader, fd *os.File) (err error) {
ta := time.Now().UnixNano()
var cache chan *Buffer = make(chan *Buffer, 16*1024)
var tb int64 = 0
go func(fd1 *os.File) {
for {
select {
case buf := <-cache:
if buf == nil {
goto end
}
nw1, ew := dst1.Write((*buf).bit[0:(*buf).blen])
if ew != nil {
err := ew
fmt.Println("-----------", err)
goto end
}
if (*buf).blen != nw1 {
err := io.ErrShortWrite
fmt.Println(err)
goto end
}
bufpool.Put((*buf))
}
}
end:
t2 := time.Now().UnixNano()
fmt.Println("eg: ", t2-ta)
fd1.Close()
}(fd)
for {
buffer := bufpool.Get().(Buffer)
nr, er := src.Read(buffer.bit)
if er != nil {
if er == io.EOF {
close(cache)
break
}
err = er
}
buffer.blen = nr
cache <- &buffer
}
tb = time.Now().UnixNano()
fmt.Println("read: ", tb-ta)
return err
}
func upload(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
if r.Method == "GET" {
t, err := template.ParseFiles("upload.gptl")
checkErr(err)
t.Execute(w, nil)
} else {
file, handle, err := r.FormFile("file")
checkErr(err)
f, err := os.OpenFile("test/"+handle.Filename, os.O_WRONLY|os.O_CREATE, 0666)
t1 := time.Now().UnixNano()
Copy(f, file, f)
checkErr(err)
defer file.Close()
t2 := time.Now().UnixNano()
fmt.Printf("sum: %v\n", t2-t1)
fmt.Fprintf(w, "upload over")
}
}
func checkErr(err error) {
if err != nil {
err.Error()
}
}
func main() {
initbt()
http.HandleFunc("/upload", upload)
fmt.Println("open")
err := http.ListenAndServe(":8888", nil)
if err != nil {
log.Fatal("listenAndServe: ", err)
}
}
}
```
该文件上传中,主要是使用了 一个新的gorotine来执行文件的写操作,后通过chan 传递携带含有文件数据的指针,
<br/>自我感觉上传性能提升了,还请各位 大神给出好的建议
有疑问加站长微信联系(非本文作者))