Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
124 lines (104 sloc) 3.09 KB

#遍历目录树

本节将介绍Go编写的find(1)命令行程序的一个相对简单的版本。

程序名为gofind.go,分为四部分介绍。gofind.go的代码将支持两个命令行选项。-d选项在作为目录的路径前面打印一个星形字符,而-f选项在作为常规文件的路径前面打印一个加号字符。

goFind.go第一部分代码如下:

package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
)

如你所见,goFind.go程序使用flag包高效地处理命令行参数。

goFind.go第二部分代码如下:

var minusD bool = false
var minusF bool = false

func walk(path string, info os.FileInfo, err error) error {
	fileInfo, err := os.Stat(path)
	if err != nil {
		return err
	}
	mode := fileInfo.Mode()
	if mode.IsRegular() && minusF {
		fmt.Println("+", path)
		return nil
	}
	if mode.IsDir() && minusD {
		fmt.Println("*", path)
		return nil
	}
	fmt.Println(path)
	return nil
}

由于minusDminusF应该可以从程序中的任何地方访问,包括walk()函数,我决定将它们设置为全局变量。IsDir()函数用于识别目录,isRegular()用于识别常规文件。

goFind.go第三部分代码如下:

func main() {
	starD := flag.Bool("d", false, "Signify directories")
	plusF := flag.Bool("f", false, "Signify regular files")
	flag.Parse()
	flags := flag.Args()
	Path := "."
	if len(flags) == 1 {
		Path = flags[0]
	}

goFind.go最后一部分代码如下:

	minusD = *starD
	minusF = *plusF
	err := filepath.Walk(Path, walk)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

执行goFind.go将创建如下的输出:

$ go run goFind.go -d -f /tmp/
* /tmp/
+ /tmp/.keystone_install_lock
* /tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D
* /tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116
+ /tmp/ExmanProcessMutex
+ /tmp/adobegc.log
/tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk
* /tmp/com.apple.launchd.h3Izgq45dz
/tmp/com.apple.launchd.h3Izgq45dz/Listeners
* /tmp/lilo.46843
+ /tmp/swtag.log
/tmp/textmate-501.sock
$ go run goFind.go -f /tmp/
/tmp/
+ /tmp/.keystone_install_lock
/tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D
/tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116
+ /tmp/ExmanProcessMutex
+ /tmp/adobegc.log
/tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk
/tmp/com.apple.launchd.h3Izgq45dz
/tmp/com.apple.launchd.h3Izgq45dz/Listeners
/tmp/lilo.46843
+ /tmp/swtag.log
/tmp/textmate-501.sock
$ go run goFind.go /tmp/
/tmp/
/tmp/.keystone_install_lock
/tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D
/tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116
/tmp/ExmanProcessMutex
/tmp/adobegc.log
/tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk
/tmp/com.apple.launchd.h3Izgq45dz
/tmp/com.apple.launchd.h3Izgq45dz/Listeners
/tmp/lilo.46843
/tmp/swtag.log
/tmp/textmate-501.sock

goFind.go的输出包含了指定根目录下的所有文件类型,包括套接字和符号链接。如果对walk()函数进行必要的更改,你可以告诉gofind.go只打印你真正感兴趣的信息。这是留给你做的练习。

现在想象一下使用C编程语言的标准库函数来实现相同的程序有多困难!

You can’t perform that action at this time.