我试图计算上传文件的sha1哈希值,但到目前为止,我还处于死胡同。示例代码如下:
err := req.ParseMultipartForm(200000)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
m := req.MultipartForm
files := m.File["Filedata"]
for i, _ := range files {
file, err := files[i].Open()
defer file.Close()
fh = getFileHash(file)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
break
}
dst, err := os.Create(baseDir+fh+".jpg")
defer dst.Close()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
break
}
if _, err := io.Copy(dst, file); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
break
}
}
getFileHash函数的内容如下:
func getFileHash (f *os.File) string {
fstat, err := f.Stat()
if err != nil {
panic(err)
}
fSize := fstat.Size()
buf := make([]byte, fSize)
hash := sha1.New()
n, err := f.Read(buf)
if _, err := io.WriteString(hash, string(buf[:n])); err != nil {
panic(err)
}
return string(hash.Sum(nil))
}
我收到以下错误,但我不确定如何解决此问题:
不能在函数参数中使用file(type multipart.File)作为类型* os.File:need type assertion
如果我使用样本哈希作为" fh "的值进行测试,它就可以了。
我知道我可以简单地保存文件,计算哈希值,然后移动文件,尽管我可以采取额外的步骤(如果可能的话)。我很感激你能给我的任何帮助。
谢谢!
答案 0 :(得分:1)
您可以同时将文件流式传输到磁盘和哈希函数。这是一个粗略的例子:
注意:它有一个警告:未对正在写入的文件检查错误。根据您的文件系统,这可能非常重要。您可能会在生产代码中考虑类似errutil的内容。
package main
import (
"crypto/sha1"
"fmt"
"io"
"os"
"strings"
)
func shaAndSave(src io.Reader) ([]byte, error) {
h := sha1.New()
dest, err := os.Create("tmpfile.txt")
if err != nil {
return nil, err
}
defer dest.Close()
t := io.TeeReader(src, h)
_, err = io.Copy(dest, t)
if err != nil {
return nil, err
}
return h.Sum(nil), nil
}
func main() {
src := strings.NewReader("pretend this was a file")
hashBytes, err := shaAndSave(src)
fmt.Printf("Returned %x and %v", hashBytes, err)
}
答案 1 :(得分:0)
来自http://golang.org/pkg/mime/multipart/#File
File是访问多部分消息的文件部分的接口。其内容可以存储在内存中或磁盘上。如果存储在磁盘上,File的底层具体类型将是* os.File。
所以你确实没有传递* os.File类型,因为它在内存中。尝试接受multipart.File作为类型。