-
Notifications
You must be signed in to change notification settings - Fork 0
/
range.go
152 lines (141 loc) · 3.66 KB
/
range.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package fs
import (
"github.com/hopeio/cherry/utils/errors/multierr"
"io/fs"
"os"
"path/filepath"
)
type FileRangeCallback = func(dir string, entry os.DirEntry) error
// 遍历根目录中的每个文件,为每个文件调用callback,包括文件夹,与filepath.WalkDir不同的是回调函数的参数不同,filepath.WalkDir的第一个参数是文件完整路径,RangeFile是文件所在目录的路径
func Range(dir string, callback FileRangeCallback) error {
entries, err := os.ReadDir(dir)
if err != nil {
return err
}
errs := multierr.New()
for _, entry := range entries {
if entry.IsDir() {
err = RangeFile(dir+PathSeparator+entry.Name(), callback)
if err != nil {
errs.Append(err)
}
}
err = callback(dir, entry)
if err != nil {
errs.Append(err)
}
}
if errs.HasErrors() {
return errs
}
return nil
}
// 指定遍历深度,0为只遍历一层,-1为无限遍历
func RangeDeep(dir string, callback FileRangeCallback, deep int) error {
entries, err := os.ReadDir(dir)
if err != nil {
return err
}
errs := multierr.New()
for _, entry := range entries {
if entry.IsDir() && deep != 0 {
err = RangeDeep(dir+PathSeparator+entry.Name(), callback, deep-1)
if err != nil {
errs.Append(err)
}
}
err = callback(dir, entry)
if err != nil {
errs.Append(err)
}
}
if errs.HasErrors() {
return errs
}
return nil
}
// 遍历根目录中的每个文件,为每个文件调用callback,不包括文件夹,与filepath.WalkDir不同的是回调函数的参数不同,filepath.WalkDir的第一个参数是文件完整路径,RangeFile是文件所在目录的路径
func RangeFile(dir string, callback FileRangeCallback) error {
entries, err := os.ReadDir(dir)
if err != nil {
return err
}
errs := multierr.New()
for _, entry := range entries {
if entry.IsDir() {
err = RangeFile(dir+PathSeparator+entry.Name(), callback)
if err != nil {
errs.Append(err)
}
} else {
err = callback(dir, entry)
if err != nil {
errs.Append(err)
}
}
}
if errs.HasErrors() {
return errs
}
return nil
}
// 指定遍历深度,0为只遍历一层,-1为无限遍历
func RangeFileDeep(dir string, callback FileRangeCallback, deep int) error {
entries, err := os.ReadDir(dir)
if err != nil {
return err
}
errs := multierr.New()
for _, entry := range entries {
if entry.IsDir() && deep != 0 {
err = RangeFileDeep(dir+PathSeparator+entry.Name(), callback, deep-1)
if err != nil {
errs.Append(err)
}
} else {
err = callback(dir, entry)
if err != nil {
errs.Append(err)
}
}
}
if errs.HasErrors() {
return errs
}
return nil
}
// RangeDir 遍历根目录中的每个文件夹,为文件夹中所有文件和目录的切片(os.ReadDir的返回)调用callback
// callback 需要处理每个文件夹下的所有文件和目录,返回值为需要递归遍历的目录和error
// 几乎每个文件夹下的文件夹都会被循环两次!
func RangeDir(dir string, callback func(dir string, entries []os.DirEntry) ([]os.DirEntry, error)) error {
entries, err := os.ReadDir(dir)
if err != nil {
return err
}
errs := multierr.New()
dirs, err := callback(dir, entries)
if err != nil {
errs.Append(err)
}
for _, entry := range dirs {
if entry.IsDir() {
err = RangeDir(dir+PathSeparator+entry.Name(), callback)
if err != nil {
errs.Append(err)
}
}
}
if errs.HasErrors() {
return errs
}
return nil
}
func WalkDirFS(fsys fs.FS, root string, fn fs.WalkDirFunc) error {
return fs.WalkDir(fsys, root, fn)
}
func Walk(root string, fn filepath.WalkFunc) error {
return filepath.Walk(root, fn)
}
func WalkDir(root string, fn fs.WalkDirFunc) error {
return filepath.WalkDir(root, fn)
}