Быстрое добавление ко всем правильным ответам (@poy и @JRLambert), предоставленным до сих пор ... Используйте io.TeeReader
или io.MultiWriter
для случаев, когда вы хотите использовать io.Copy
более одного раза.Ниже приведены некоторые примеры использования каждого .
Использование io.TeeReader
package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
)
func main() {
sourceFile, _ := os.Open("source/ebook.pdf")
var buf bytes.Buffer
tee := io.TeeReader(sourceFile, &buf)
process := func(sourceReader io.Reader) {
targetFile, _ := os.Create("target/ebook.pdf")
defer targetFile.Close()
if _, err := io.Copy(targetFile, sourceReader); err != nil {
fmt.Println(err)
}
}
process(tee)
fmt.Println(checksum(&buf))
}
func checksum(buf *bytes.Buffer) string {
h := md5.New()
b, _ := ioutil.ReadAll(buf)
if _, err := h.Write(b); err != nil {
fmt.Println(err)
}
return hex.EncodeToString(h.Sum(nil)[:16])
}
Использование io.MultiWriter
package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
)
func main() {
sourceFile, _ := os.Open("source/ebook.pdf")
process := func(sourceReader io.Reader) {
targetFile, _ := os.Create("target/ebook.pdf")
defer targetFile.Close()
var buf1, buf2 bytes.Buffer
w := io.MultiWriter(targetFile, &buf1, &buf2)
if _, err := io.Copy(w, sourceReader); err != nil {
fmt.Println(err)
}
fmt.Println(checksum(&buf1))
fmt.Println(checksum(&buf2))
}
process(sourceFile)
}
func checksum(buf *bytes.Buffer) string {
h := md5.New()
b, _ := ioutil.ReadAll(buf)
if _, err := h.Write(b); err != nil {
fmt.Println(err)
}
return hex.EncodeToString(h.Sum(nil)[:16])
}