I write a file uploader with Go. I would like to have md5 of the file as a file name when I save it to the disk.
What is the best way to solve this problem?
I save a file this way:
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())
}
here is an example using io.TeeReader to perform both computation and copy at same time
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("
%x", h.Sum(nil))
}
// Output:
//some data
//1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee
And the comparison test for correctness
$ echo -n "some data" | sha256sum -
1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee -
Instead of using io.TeeReader
I have used io.MultiWriter
to create 2 buffers (I will use the first buffer to calculate md5 and the second to write to a file with md5 name)
lmt := io.LimitReader(buf, maxSize + 1)
hash := md5.New()
var buf1, buf2 bytes.Buffer
w := io.MultiWriter(&buf1, &buf2)
if _, err := io.Copy(w, lmt); err != nil {
log.Fatal(err)
}
if _, err := io.Copy(hash, &buf1); err != nil {
log.Fatal(err)
}
fmt.Println("md5 is: ", hex.EncodeToString(hash.Sum(nil)))
// Now we can create file with os.Openfile passing md5 name as an argument + write &buf2 to this file