golang -如何检查multipart.文件信息

euoag5mw  于 2023-01-22  发布在  Go
关注(0)|答案(4)|浏览(231)

当用户使用r.FormFile("file")上传文件时,您会得到一个multipart.File、一个multipart.FileHeader和一个error
我的问题是如何获取上传文件的信息,比如它的大小,如果是图片的话它的尺寸,等等。
我真的不知道从哪里开始,所以任何帮助都将是伟大的。

kyvafyod

kyvafyod1#

要获取文件大小和MIME类型:

// 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\n", multipartFileHeader.Filename)
        log.Printf("Size: %#v\n", file.(Sizer).Size())
        log.Printf("MIME: %#v\n", http.DetectContentType(fileHeader))
}

样本输出:

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"
6yoyoihd

6yoyoihd2#

可以从返回的multipart.FileHeader中获取文件名和MIME类型。
大多数元数据将取决于文件类型,如果是图像,你应该能够使用标准库中的DecodeConfig函数,PNGJPEGGIF,来获取尺寸(和颜色模型)。
还有很多Go语言库可以用于其他类型的文件,它们也有类似的功能。
编辑:golang-nuts邮件组有一个很好的例子。

7dl7o3gd

7dl7o3gd3#

您可以从Content-Length标头中获取有关文件大小的近似信息。不建议这样做,因为此标头可以更改。
更好的方法是使用ReadFrom方法:

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.
atmip9wb

atmip9wb4#

另一种我发现的非常简单的测试方法是将测试资产放在相对于包的test_data目录中。在我的测试文件中,我通常创建一个帮助器来创建一个 * http.request的示例,这允许我非常容易地在multipart.file上运行表测试,(为了简洁起见,删除了错误检查)。

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
}

相关问题