我用Go编写了一个文件上传器。将文件的md5保存到磁盘时,我希望将其作为文件名。
解决此问题的最佳方法是什么?
我这样保存文件:
reader, _ := r.MultipartReader()
p, _ := reader.NextPart()
f, _ := os.Create("./filename") // here I need md5 as a file name
defer f.Close()
lmt := io.LimitReader(p, maxSize + 1)
written, _ := io.Copy(f, lmt)
if written > maxSize {
os.Remove(f.Name())
}
答案 0 :(得分:4)
这是一个使用io.TeeReader同时执行计算和复制的示例
https://play.golang.org/p/IJJQiaeTOBh
package main
import (
"crypto/sha256"
"fmt"
"io"
"os"
"strings"
)
func main() {
var s io.Reader = strings.NewReader("some data")
// maxSize := 4096
// s = io.LimitReader(s, maxSize + 1)
h := sha256.New()
tr := io.TeeReader(s, h)
io.Copy(os.Stdout, tr)
fmt.Printf("\n%x", h.Sum(nil))
}
// Output:
//some data
//1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee
和比较测试的正确性
$ echo -n "some data" | sha256sum -
1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee -
答案 1 :(得分:1)
我使用AT+FCLASS=8
来创建2个缓冲区(而不是使用io.TeeReader
)(我将使用第一个缓冲区来计算md5,第二个缓冲区来写入具有md5名称的文件)
io.MultiWriter
答案 2 :(得分:0)
我喜欢 TeeReader here 的解决方案,但将其简化如下:
type HashReader struct {
io.Reader
hash.Hash
}
func NewHashReader(r io.Reader, h hash.Hash) HashReader {
return HashReader{io.TeeReader(r, h), h}
}
func NewMD5Reader(r io.Reader) HashReader {
return NewHashReader(r, md5.New())
}
func main() {
dataReader := bytes.NewBufferString("Hello, world!")
hashReader := NewMD5Reader(dataReader)
resultBytes := make([]byte, dataReader.Len())
_, err := hashReader.Read(resultBytes)
if err != nil {
fmt.Println(err)
}
fmt.Println(hex.EncodeToString(hashReader.Sum(nil)))
}
md5 的十六进制编码字符串对我来说看起来更熟悉,但可以随意编码 hashReader.Sum(nil)
的结果字节数组。
附言关于操场示例的另一件事。他们在 EOF 上分配 md5 结果,但绝对不是所有消费者都在 EOF 之前阅读。由于 Hash 对象存储了当前的哈希计算,因此消费完成后调用 hashReader.Sum
并使用结果就足够了。