[golang] golang简洁的文件上传与接收服务

最近自己阿里云上的文件共享总是不怎么方便,本来是用的samba,用着用着就用不乐,见鬼,于是只能自己整个简洁点的了。

不过用go的话也非常快啦。

需要注意的是http post文件一般用的都是multipart表单格式,看一看就好了。

uploadhandle

package main

import (
    "io"
    "io/ioutil"
    "net/http"
    "os"
    "fmt"
)

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    reader, err := r.MultipartReader()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    for {
        part, err := reader.NextPart()
        if err == io.EOF {
            break
        }

        fmt.Printf("FileName=[%s], FormName=[%s]\n", part.FileName(), part.FormName())

        if part.FileName() == "" {//formdata
            data, _ := ioutil.ReadAll(part)
            fmt.Printf("FormData=[%s]\n", string(data))
        } else {
            file, _ := os.Create("./" + part.FileName())
            defer file.Close()
            io.Copy(file, part)
        }
    }
}

func main() {
    http.HandleFunc("/upload", uploadHandler)
    http.ListenAndServe(":8080", nil)
}

upload.go

package main

import (
    "bytes"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "os"
)

func postFile(filename string, target_url string) (*http.Response, error) {
    body_buf := bytes.NewBufferString("")
    body_writer := multipart.NewWriter(body_buf)

    // use the body_writer to write the Part headers to the buffer
    _, err := body_writer.CreateFormFile("userfile", filename)
    if err != nil {
        fmt.Println("error writing to buffer")
        return nil, err
    }

    // the file data will be the second part of the body
    fh, err := os.Open(filename)
    if err != nil {
        fmt.Println("error opening file")
        return nil, err
    }
    // need to know the boundary to properly close the part myself.
    boundary := body_writer.Boundary()
    //close_string := fmt.Sprintf("\r\n--%s--\r\n", boundary)
    close_buf := bytes.NewBufferString(fmt.Sprintf("\r\n--%s--\r\n", boundary))

    // use multi-reader to defer the reading of the file data until
    // writing to the socket buffer.
    request_reader := io.MultiReader(body_buf, fh, close_buf)
    fi, err := fh.Stat()
    if err != nil {
        fmt.Printf("Error Stating file: %s", filename)
        return nil, err
    }
    req, err := http.NewRequest("POST", target_url, request_reader)
    if err != nil {
        return nil, err
	}
	
    // Set headers for multipart, and Content Length
    req.Header.Add("Content-Type", "multipart/form-data; boundary="+boundary)
    req.ContentLength = fi.Size() + int64(body_buf.Len()) + int64(close_buf.Len())

    return http.DefaultClient.Do(req)
}

// sample usage
func main() {
    list := os.Args
    n := len(list)
    if n != 2 {
        return
    }
    target_url := "http://127.0.0.1:8080/upload"
    filename := list[1]
    postFile(filename, target_url)
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Golang 的 multipart 包来实现分块接收文件上传服务端。具体步骤如下: 1. 定义一个路由,处理客户端上传文件的请求,例如: ```go http.HandleFunc("/upload", uploadHandler) ``` 2. 在 uploadHandler 函数中,使用 multipart 包解析客户端发送的请求,获取上传文件的内容和信息,例如: ```go func uploadHandler(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(32 << 20) // 限制上传文件大小为 32MB if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } file, header, err := r.FormFile("file") // 获取上传文件的内容和信息 if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer file.Close() // 处理上传文件的内容和信息 // ... } ``` 3. 在处理上传文件的内容和信息时,可以将文件分块读取并保存到本地或者云端存储中,例如: ```go const ( maxChunkSize = 10 * 1024 * 1024 // 限制每个分块大小为 10MB ) func uploadHandler(w http.ResponseWriter, r *http.Request) { // ... totalSize := header.Size // 获取上传文件的总大小 chunks := int(math.Ceil(float64(totalSize) / float64(maxChunkSize))) // 计算需要分成几个块 for i := 0; i < chunks; i++ { chunkSize := maxChunkSize if i == chunks-1 { chunkSize = int(totalSize) - i*maxChunkSize // 最后一个块的大小可能不足 maxChunkSize } chunk := make([]byte, chunkSize) _, err := file.Read(chunk) // 读取分块内容 if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // 将分块内容保存到本地或者云端存储中 // ... } // ... } ``` 这样就可以实现 Golang 分块接收文件上传服务端了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值