2013-06-16 03:04
浏览 371


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.

图片转代码服务由CSDN问答提供 功能建议

当用户使用r.FormFile(“ file”)上传文件时,会得到一个multipart.File, multipart.FileHeader和一个错误。

我的问题是如何获取有关上载文件的信息,例如,文件的大小,如果是图像,则是尺寸,等等。 。


  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

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
    打赏 评论

相关推荐 更多相似问题