golang文件上传和下载
本文内容纲要:
-【代码】golang实现的文件服务(包括上传,下载的server端和client端)
【代码】golang实现的文件服务(包括上传,下载的server端和client端)
//下载(支持断电续传)(client)
packagemain
import(
"http"
"os"
"io"
"strconv"
)
const(
UA="GolangDownloaderfromKejibo.com"
)
funcmain(){
f,err:=os.OpenFile("./file.exe",os.O_RDWR,0666)//其实这里的O_RDWR应该是O_RDWR|O_CREATE,也就是文件不存在的情况下就建一个空文件,但是因为windows下还有BUG,如果使用这个O_CREATE,就会直接清空文件,所以这里就不用了这个标志,你自己事先建立好文件。
iferr!=nil{panic(err)}
stat,err:=f.Stat()//获取文件状态
iferr!=nil{panic(err)}
f.Seek(stat.Size,0)//把文件指针指到文件末,当然你说为何不直接用O_APPEND模式打开,没错是可以。我这里只是试验。
url:="http://dl.google.com/chrome/install/696.57/chrome_installer.exe"
varreqhttp.Request
req.Method="GET"
req.UserAgent=UA
req.Close=true
req.URL,err=http.ParseURL(url)
iferr!=nil{panic(err)}
header:=http.Header{}
header.Set("Range","bytes="+strconv.Itoa64(stat.Size)+"-")
req.Header=header
resp,err:=http.DefaultClient.Do(&req)
iferr!=nil{panic(err)}
written,err:=io.Copy(f,resp.Body)
iferr!=nil{panic(err)}
println("written:",written)
}
//下载(server)
packagemain
import(
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"path"
"strconv"
)
vardirstring
varportint
varstaticHandlerhttp.Handler
//初始化参数
funcinit(){
dir=path.Dir(os.Args[0])
flag.IntVar(&port,"port",800,"服务器端口")
flag.Parse()
fmt.Println("dir:",http.Dir(dir))
staticHandler=http.FileServer(http.Dir(dir))
}
funcmain(){
http.HandleFunc("/",StaticServer)
err:=http.ListenAndServe(":"+strconv.Itoa(port),nil)
iferr!=nil{
log.Fatal("ListenAndServe:",err)
}
}
//静态文件处理
funcStaticServer(whttp.ResponseWriter,req*http.Request){
fmt.Println("path:"+req.URL.Path)
ifreq.URL.Path!="/down/"{
staticHandler.ServeHTTP(w,req)
return
}
io.WriteString(w,"hello,world!\n")
}
//上传(client)
packagemain
import(
"bytes"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
)
funcpostFile(filenamestring,targetUrlstring)error{
bodyBuf:=&bytes.Buffer{}
bodyWriter:=multipart.NewWriter(bodyBuf)
//关键的一步操作
fileWriter,err:=bodyWriter.CreateFormFile("uploadfile",filename)
iferr!=nil{
fmt.Println("errorwritingtobuffer")
returnerr
}
//打开文件句柄操作
fh,err:=os.Open(filename)
iferr!=nil{
fmt.Println("erroropeningfile")
returnerr
}
//iocopy
_,err=io.Copy(fileWriter,fh)
iferr!=nil{
returnerr
}
contentType:=bodyWriter.FormDataContentType()
bodyWriter.Close()
resp,err:=http.Post(targetUrl,contentType,bodyBuf)
iferr!=nil{
returnerr
}
deferresp.Body.Close()
resp_body,err:=ioutil.ReadAll(resp.Body)
iferr!=nil{
returnerr
}
fmt.Println(resp.Status)
fmt.Println(string(resp_body))
returnnil
}
//sampleusage
funcmain(){
target_url:="http://localhost:9090/upload"
filename:="./astaxie.pdf"
postFile(filename,target_url)
}
//上传(server)
packagemain
import(
"crypto/md5"
"flag"
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
"path"
"strconv"
"time"
)
vardirstring
varportint
//初始化参数
funcinit(){
dir=path.Dir(os.Args[0])
flag.IntVar(&port,"port",800,"服务器端口")
flag.Parse()
fmt.Println("dir:",http.Dir(dir))
}
funcmain(){
http.HandleFunc("/upload",upload)
err:=http.ListenAndServe(":"+strconv.Itoa(port),nil)
iferr!=nil{
log.Fatal("ListenAndServe:",err)
}
}
//处理/upload逻辑
funcupload(whttp.ResponseWriter,r*http.Request){
fmt.Println("method:",r.Method)//获取请求的方法
ifr.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")
iferr!=nil{
fmt.Println(err)
return
}
deferfile.Close()
fmt.Fprintf(w,"%v",handler.Header)
f,err:=os.OpenFile("./upload/"+handler.Filename,os.O_WRONLY|os.O_CREATE,0666)
iferr!=nil{
fmt.Println(err)
return
}
deferf.Close()
io.Copy(f,file)
}
}
本文内容总结:【代码】golang实现的文件服务(包括上传,下载的server端和client端),
原文链接:https://www.cnblogs.com/zhangym/p/5841732.html