首页 > 解决方案 > 从文件和存储文件创建 sha256 的最佳模式

问题描述

我正在编写一个接收文件作为上传的网络服务器multipart/form-data。我正在从请求中生成文件 sha256,但由于Reader接口的性质,我无法重用数据也将文件上传到文件管理器。这些文件可以是几百个MB。存储内容的最佳方式是什么?我可以复制内容,但我担心这可能会浪费内存资源。

编辑

func uploadFile(w http.ResponseWriter, r *http.Request) {
    f, err := r.MultipartForm.File["capture"][0].Open()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer f.Close()
    hash, err := createSha(f)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
}

func createSha(image multipart.File) (hash.Hash, error) {
    sha := sha256.New()
    // This cause the contents of image to no longer be available to be read again to be stored on the filer
    if _, err := io.Copy(sha, image); err != nil {
        return nil, err
    }
    return sha, nil
}

标签: go

解决方案


您可能会使用io.MultiWriter(...)同时将数据发送到多个输出流,例如散列和一些远程写入器。

例如(大致):

sha := sha256.New()
filer := filer.New(...) // Some Writer that stores the bytes for you?
err := io.Copy(io.MultiWriter(sha, filer), r)
// TODO: handle error
// Now sha.Sum(nil) has the file digest and "filer" got sent all the bytes.

请注意,io.Multiwriter可以根据需要使用任意数量的写入器,因此您可以同时计算额外的哈希值(例如 md5、sha1 等),甚至可以将文件发送到多个位置,例如:

md5, sha1, sha256, sha512 := md5.New(), sha1.New(), sha256.New(), sha512.New()
s3Writer, gcsWriter := filer.NewS3Writer(), filer.NewGCSWriter()
mw := io.MultiWriter(awsWriter, gcsWriter, md5, sha1, sha256, sha512)
err := io.Copy(mw, r)
// TODO: handle error
// Now you've got all the hashes for the file and it's stored in the cloud.

推荐阅读