08.16 遍历目录树
本节将介绍Go编写的find(1)命令行程序的一个相对简单的版本。
程序名为gofind.go,分为四部分介绍。gofind.go的代码将支持两个命令行选项。-d选项在作为目录的路径前面打印一个星形字符,而-f选项在作为常规文件的路径前面打印一个加号字符。
goFind.go第一部分代码如下:
1
package main
2
3
import (
4
"flag"
5
"fmt"
6
"os"
7
"path/filepath"
8
)
Copied!
如你所见,goFind.go程序使用flag包高效地处理命令行参数。
goFind.go第二部分代码如下:
1
var minusD bool = false
2
var minusF bool = false
3
4
func walk(path string, info os.FileInfo, err error) error {
5
fileInfo, err := os.Stat(path)
6
if err != nil {
7
return err
8
}
9
mode := fileInfo.Mode()
10
if mode.IsRegular() && minusF {
11
fmt.Println("+", path)
12
return nil
13
}
14
if mode.IsDir() && minusD {
15
fmt.Println("*", path)
16
return nil
17
}
18
fmt.Println(path)
19
return nil
20
}
Copied!
由于minusDminusF应该可以从程序中的任何地方访问,包括walk()函数,我决定将它们设置为全局变量。IsDir()函数用于识别目录,isRegular()用于识别常规文件。
goFind.go第三部分代码如下:
1
func main() {
2
starD := flag.Bool("d", false, "Signify directories")
3
plusF := flag.Bool("f", false, "Signify regular files")
4
flag.Parse()
5
flags := flag.Args()
6
Path := "."
7
if len(flags) == 1 {
8
Path = flags[0]
9
}
Copied!
goFind.go最后一部分代码如下:
1
minusD = *starD
2
minusF = *plusF
3
err := filepath.Walk(Path, walk)
4
if err != nil {
5
fmt.Println(err)
6
os.Exit(1)
7
}
8
}
Copied!
执行goFind.go将创建如下的输出:
1
$ go run goFind.go -d -f /tmp/
2
* /tmp/
3
+ /tmp/.keystone_install_lock
4
* /tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D
5
* /tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116
6
+ /tmp/ExmanProcessMutex
7
+ /tmp/adobegc.log
8
/tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk
9
* /tmp/com.apple.launchd.h3Izgq45dz
10
/tmp/com.apple.launchd.h3Izgq45dz/Listeners
11
* /tmp/lilo.46843
12
+ /tmp/swtag.log
13
/tmp/textmate-501.sock
14
$ go run goFind.go -f /tmp/
15
/tmp/
16
+ /tmp/.keystone_install_lock
17
/tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D
18
/tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116
19
+ /tmp/ExmanProcessMutex
20
+ /tmp/adobegc.log
21
/tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk
22
/tmp/com.apple.launchd.h3Izgq45dz
23
/tmp/com.apple.launchd.h3Izgq45dz/Listeners
24
/tmp/lilo.46843
25
+ /tmp/swtag.log
26
/tmp/textmate-501.sock
27
$ go run goFind.go /tmp/
28
/tmp/
29
/tmp/.keystone_install_lock
30
/tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D
31
/tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116
32
/tmp/ExmanProcessMutex
33
/tmp/adobegc.log
34
/tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk
35
/tmp/com.apple.launchd.h3Izgq45dz
36
/tmp/com.apple.launchd.h3Izgq45dz/Listeners
37
/tmp/lilo.46843
38
/tmp/swtag.log
39
/tmp/textmate-501.sock
Copied!
goFind.go的输出包含了指定根目录下的所有文件类型,包括套接字和符号链接。如果对walk()函数进行必要的更改,你可以告诉gofind.go只打印你真正感兴趣的信息。这是留给你做的练习。
现在想象一下使用C编程语言的标准库函数来实现相同的程序有多困难!
Last modified 2yr ago
Copy link