github.com/benchkram/bob@v0.0.0-20240314204020-b7a57f2f9be9/pkg/filehash/filehash.go (about) 1 package filehash 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "hash" 7 "io" 8 "os" 9 ) 10 11 type H struct { 12 hash hash.Hash 13 buffer []byte 14 } 15 16 func New() *H { 17 return &H{ 18 hash: hashFunc(), 19 buffer: make([]byte, 32*1024), 20 } 21 } 22 23 func (h *H) AddFile(file string) error { 24 f, err := os.Open(file) 25 if err != nil { 26 return fmt.Errorf("failed to open: %w", err) 27 } 28 29 err = h.AddBytes(f) 30 f.Close() // avoiding defer for performance 31 32 return err 33 } 34 35 func (h *H) AddBytes(r io.Reader) error { 36 if _, err := io.CopyBuffer(h.hash, r, h.buffer); err != nil { 37 return fmt.Errorf("failed to copy: %w", err) 38 } 39 return nil 40 } 41 42 func (h *H) Sum() []byte { 43 return h.hash.Sum(nil) 44 } 45 46 // HashOfFile gives hash of a file content 47 func HashOfFile(path string) (string, error) { 48 h := New() 49 err := h.AddFile(path) 50 if err != nil { 51 return "", err 52 } 53 return hex.EncodeToString(h.Sum()), nil 54 }