douqiu1604 2013-06-16 03:04
浏览 629
已采纳

golang-如何检查multipart.file信息

When a user uploads a file, using r.FormFile("file") you get a multipart.File, a multipart.FileHeader and an error.

My question is how to just obtain information about the uploaded file for example, it's size, and if it's an image it's demensions, and so on and so forth.

I have literally got no idea on where to start so any help would be great.

  • 写回答

4条回答 默认 最新

  • douyi3760 2013-06-16 10:13
    关注

    The file name and MIME type can be obtained from the returned multipart.FileHeader.

    Most further meta-data will depend on the file type. If it's an image, you should be able to use the DecodeConfig functions in the standard library, for PNG, JPEG and GIF, to obtain the dimensions (and color model).

    There are many Go libraries available for other file types as well, which will have similar functions.

    EDIT: There's a good example on the golang-nuts mail group.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • doulu4233 2016-07-04 02:21
    关注

    You can get approximate information about the size of file from Content-Length header. This is not recommended, because this header can be changed.

    A better way is to use ReadFrom method:

    clientFile, handler, err := r.FormFile("file") // r is *http.Request
    var buff bytes.Buffer
    fileSize, err := buff.ReadFrom(clientFile)
    fmt.Println(fileSize) // this will return you a file size.
    
    评论
  • douken0530 2016-12-01 23:03
    关注

    To get the file size and MIME type:

    // Size constants
    const (
            MB = 1 << 20
    )
    
    type Sizer interface {
            Size() int64
    }
    
    func Sample(w http.ResponseWriter, r *http.Request) error {
            if err := r.ParseMultipartForm(5 * MB); err != nil {
                    return err
            }
    
            // Limit upload size
            r.Body = http.MaxBytesReader(w, r.Body, 5*MB) // 5 Mb
    
            //
            file, multipartFileHeader, err := r.FormFile("file")
    
            // Create a buffer to store the header of the file in
            fileHeader := make([]byte, 512)
    
            // Copy the headers into the FileHeader buffer
            if _, err := file.Read(fileHeader); err != nil {
                    return err
            }
    
            // set position back to start.
            if _, err := file.Seek(0, 0); err != nil {
                    return err
            }
    
            log.Printf("Name: %#v
    ", multipartFileHeader.Filename)
            log.Printf("Size: %#v
    ", file.(Sizer).Size())
            log.Printf("MIME: %#v
    ", http.DetectContentType(fileHeader))
    }
    

    Sample output:

    2016/12/01 15:00:06 Name: "logo_35x30_black.png"
    2016/12/01 15:00:06 Size: 18674
    2016/12/01 15:00:06 MIME: "image/png"
    
    评论
  • doudi5524 2019-09-18 02:05
    关注

    Another way I've found pretty simple for this type of testing is to place test assets in a test_data directory relative to the package. Within my test file I normally create a helper that creates an instance of *http.Request, which allows me to run table test pretty easily on multipart.File, (errors checking removed for brevity).

    func createMockRequest(pathToFile string) *http.Request {
        file, err := os.Open(pathToFile)
        if err != nil {
            return nil
        }
        defer file.Close()
    
        body := &bytes.Buffer{}
        writer := multipart.NewWriter(body)
        part, err := writer.CreateFormFile("file", filepath.Base(pathToFile))
        if err != nil {
            return nil
        }
        _, _ = io.Copy(part, file)
    
        err = writer.Close()
        if err != nil {
            return nil
        }
        // the body is the only important data for creating a new request with the form data attached
        req, _ := http.NewRequest("POST", "", body)
        req.Header.Set("Content-Type", writer.FormDataContentType())
        return req
    }
    
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 Java中import为灰色
  • ¥15 手机等其他智能设备被监听
  • ¥15 在win10 64位的vs打包MSI文件,放到win7 64位上安装成可执行exe文件后,点击程序不运行。
  • ¥50 大众点评用户浏览/消费记录爬虫
  • ¥15 求制作一个个人网页,
  • ¥15 寻涂色内存脚本作者有项目有市场有资源.却技术
  • ¥15 蓝桥杯c51单片机问题
  • ¥15 ajax跨域问题请求修改代码
  • ¥15 python matplotlib
  • ¥15 短信测压+语音,有偿,必须用Python