This repository has been archived by the owner on Sep 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fs.go
81 lines (66 loc) · 1.4 KB
/
fs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package fs
import (
"crypto/sha256"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
"time"
"github.com/fedragon/go-dedup/internal"
"github.com/fedragon/go-dedup/internal/metrics"
log "github.com/sirupsen/logrus"
)
func hash(metrics *metrics.Metrics, path string) ([]byte, error) {
stop := metrics.Record("hash")
defer func() { _ = stop() }()
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer func() {
if err := f.Close(); err != nil {
log.Printf(err.Error())
}
}()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
return nil, err
}
return h.Sum(nil), nil
}
func Walk(metrics *metrics.Metrics, root string, fileTypes []string) <-chan internal.Media {
media := make(chan internal.Media)
go func() {
defer close(media)
typesMap := make(map[string]int)
for _, t := range fileTypes {
typesMap[t] = 1
}
err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
_ = metrics.Increment("walk")
if !d.IsDir() {
ext := strings.ToLower(filepath.Ext(d.Name()))
if typesMap[ext] > 0 {
bytes, err := hash(metrics, path)
if err != nil {
return err
}
media <- internal.Media{
Path: path,
Hash: bytes,
Timestamp: time.Now(),
}
}
}
return nil
})
if err != nil {
media <- internal.Media{Err: err}
}
}()
return media
}