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  }