Go语言开发(十二)、Go语言常用标准库二
Go语言开发(十二)、Go语言常用标准库二
一、os1、os简介os 包提供了不依赖平台的操作系统函数接口,设计像Unix风格,但错误处理是go风格,当os包使用时,如果失败后返回错误类型而不是错误数量。 2、os常用接口func Hostname() (name string,err error) // Hostname返回内核提供的主机名 func Environ() []string // Environ返回表示环境变量的格式为”key=value”的字符串的切片拷贝 func Getenv(key string) string // Getenv检索并返回名为key的环境变量的值 func Getpid() int // Getpid返回调用者所在进程的进程ID func Exit(code int) // Exit让当前程序以给出的状态码code退出。一般来说,状态码0表示成功,非0表示出错。程序会立刻终止,defer的函数不会被执行 func Stat(name string) (fi FileInfo,err error) // 获取文件信息 func Getwd() (dir string,err error) // Getwd返回一个对应当前工作目录的根路径 func Mkdir(name string,perm FileMode) error // 使用指定的权限和名称创建一个目录 func MkdirAll(path string,perm FileMode) error // 使用指定的权限和名称创建一个目录,包括任何必要的上级目录,并返回nil,否则返回错误 func Remove(name string) error // 删除name指定的文件或目录 func TempDir() string // 返回一个用于保管临时文件的默认目录 var Args []string // os.Args返回一个字符串数组,其中第一个参数就是执行文件本身 os示例: package main import ( "fmt" "os" ) func main() { // 预定义变量,保存命令行参数 fmt.Println(os.Args) // 获取host name fmt.Println(os.Hostname()) fmt.Println(os.Getpid()) // 获取全部环境变量 env := os.Environ() for k,v := range env { fmt.Println(k,v) } // 终止程序 // os.Exit(1) // 获取一条环境变量 fmt.Println(os.Getenv("PATH")) // 获取当前目录 dir,err := os.Getwd() fmt.Println(dir,err) // 创建目录 err = os.Mkdir(dir+"/new_file",0755) fmt.Println(err) // 创建目录 err = os.MkdirAll(dir+"/new",0755) fmt.Println(err) // 删除目录 err = os.Remove(dir + "/new_file") err = os.Remove(dir + "/new") fmt.Println(err) // 创建临时目录 tmp_dir := os.TempDir() fmt.Println(tmp_dir) } 3、File结构体func Create(name string) (file *File,err error) // Create采用模式0666创建一个名为name的文件,如果文件已存在会截断(为空文件) func Open(name string) (file *File,err error) // Open打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据 func (f *File) Stat() (fi FileInfo,err error) // Stat返回描述文件f的FileInfo类型值 func (f *File) Readdir(n int) (fi []FileInfo,err error) // Readdir读取目录f的内容,返回一个有n个成员的[]FileInfo func (f *File) Read(b []byte) (n int,err error) // Read方法从f中读取最多len(b)字节数据并写入b func (f *File) WriteString(s string) (ret int,err error) // 向文件中写入字符串 func (f *File) Sync() (err error) // Sync递交文件的当前内容进行稳定的存储 func (f *File) Close() error // Close关闭文件f,使文件不能用于读写 File示例: package main import ( "fmt" "os" "time" ) func main() { // 获取当前目录 dir,err) file := dir + "/new" var fh *os.File fi,_ := os.Stat(file) if fi == nil { fh,_ = os.Create(file) // 文件不存在就创建 } else { fh,_ = os.OpenFile(file,os.O_RDWR,0666) // 文件存在就打开 } w := []byte("hello go language" + time.Now().String()) n,err := fh.Write(w) fmt.Println(n,err) // 设置下次读写位置 ret,err := fh.Seek(0,0) fmt.Printf("%s %v %vn","当前文件指针位置",ret,err) b := make([]byte,128) n,err = fh.Read(b) fmt.Printf("%d %v %sn",n,err,string(b)) fh.Close() } 4、FileInfo结构体FileInfo用来描述一个文件对象。 type FileInfo interface { Name() string // base name of the file Size() int64 // length in bytes for regular files; system-dependent for others Mode() FileMode // file mode bits ModTime() time.Time // modification time IsDir() bool // abbreviation for Mode().IsDir() Sys() interface{} // underlying data source (can return nil) }
package main import ( "os" ) func main() { file := "/home/user/hello.go" fi,_ := os.Create(file) // 文件不存在就创建 fh.Write([]byte("package mainnfunc main(){n}n")) } else { fh,_ := os.OpenFile(file,0666) // 文件存在就打开 fh.Write([]byte("package mainnfunc main(){n}n")) } } 二、bufio1、bufio简介bufio模块通过对io模块的封装,提供了数据缓冲功能,能够一定程度减少大块数据读写带来的开销。 2、Readertype Reader struct { buf []byte rd io.Reader // reader provided by the client r,w int // buf read and write positions err error lastByte int lastRuneSize int } 可以通过NewReader函数创建bufio.Reader对象,函数接收一个io.Reader作为参数。因此,bufio.Reader不能直接使用,需要绑定到某个io.Reader上。 func NewReader(rd io.Reader) *Reader func NewReaderSize(rd io.Reader,size int) *Reader // 可以配置缓冲区的大小 相较于io.Reader,bufio.Reader提供了很多实用的方法,能够更有效的对数据进行读取。bufio.Reader能够对Reader进行细粒度的操作: func (b *Reader) Read(p []byte) (n int,err error) func (b *Reader) Discard(n int) (discarded int,err error) func (b *Reader) Peek(n int) ([]byte,error) func (b *Reader) Reset(r io.Reader) bufio.Reader还提供了多个更高抽象层次的方法对数据进行简单的结构化读取,如下: func (b *Reader) ReadByte() (byte,error) func (b *Reader) ReadRune() (r rune,size int,err error) func (b *Reader) ReadLine() (line []byte,isPrefix bool,err error) func (b *Reader) ReadBytes(delim byte) ([]byte,error) func (b *Reader) ReadString(delim byte) (string,error) bufio.Reader使用示例: package main import ( "strings" "fmt" "bufio" ) func main() { r := strings.NewReader("hello world !") reader := bufio.NewReader(r) bytes,_ := reader.Peek(5) fmt.Printf("%sn",bytes) n,_ := reader.Read(bytes) fmt.Println(n) reader.Discard(1) for { str,err := reader.ReadString(byte(‘ ‘)) fmt.Println(str) if err != nil { return } } } // output // hello // 5 // world // ! 3、Writertype Writer struct { err error buf []byte n int wr io.Writer } func NewWriter(w io.Writer) *Writer func NewWriterSize(w io.Writer,size int) *Writer 创建Writer对象的接口 func (b *Writer) Write(p []byte) (nn int,err error) // 写入n byte数据 func (b *Writer) Reset(w io.Writer) // 重置当前缓冲区 func (b *Writer) Flush() error // 清空当前缓冲区,将数据写入输出 func (b *Writer) WriteByte(c byte) error // 写入一个字节 func (b *Writer) WriteRune(r rune) (size int,err error) // 写入一个字符 func (b *Writer) WriteString(s string) (int,error) // 写入一个字符串 func (b *Writer) Available() int // 缓存中有多少字节空间可用 func (b *Writer) Buffered() int // 当前缓存已经写入了多少字节 func (b *Writer) ReadFrom(r io.Reader) (n int64,err error) // 实现io.ReaderFrom 4、ReadWritertype ReadWriter struct { *Reader *Writer } ReadWriter实现了io.ReadWriter。 5、Scannertype Scanner struct { r io.Reader // The reader provided by the client. split SplitFunc // The function to split the tokens. maxTokenSize int // Maximum size of a token; modified by tests. token []byte // Last token returned by split. buf []byte // Buffer used as argument to split. start int // First non-processed byte in buf. end int // End of data in buf. err error // Sticky error. empties int // Count of successive empty tokens. scanCalled bool // Scan has been called; buffer is in use. done bool // Scan has finished. } 工程开发中推荐使用Scanner对数据进行读取,而非直接使用Reader类。Scanner可以通过splitFunc将输入数据拆分为多个token,然后依次进行读取。 scanner := bufio.NewScanner(os.StdIn) scanner.split(bufio.ScanWords) 设置分割方式 func (s *Scanner) Scan() bool func (s *Scanner) Text() string func (s *Scanner) Bytes() []byte 在完成Scanner初始化后,通过Scan方法可以在输入中向前读取一个token,读取成功返回True;使用Text和Bytes方法获取token,Text返回一个字符串,Bytes返回字节数组。 package main import ( "strings" "fmt" "bufio" ) func main() { scanner := bufio.NewScanner(strings.NewReader("hello world !")) scanner.Split(bufio.ScanWords) for scanner.Scan() { fmt.Println(scanner.Text()) } } // output // hello // world // ! 三、ioutil1、ioutil简介ioutil提供了对io包的封装函数。 2、ReadAll
s := strings.NewReader("Hello World!") ra,_ := ioutil.ReadAll(s) fmt.Printf("%s",ra) // Hello World!
content,err := ioutil.ReadFile("/home/user/hello.txt") if err != nil { log.Fatal(err) } fmt.Printf("File contents: %s",content) 3、WriteFile
filename := "/home/user/hello.txt" data := []byte("Hello World!") ioutil.WriteFile(filename,data,os.ModeAppend) contents,_ := ioutil.ReadFile(filename) fmt.Printf("%s",contents) // Hello World! 4、ReadDir
rd,err := ioutil.ReadDir("/home/user") for _,fi := range rd { fmt.Println("") fmt.Println(fi.Name()) fmt.Println(fi.IsDir()) fmt.Println(fi.Size()) fmt.Println(fi.ModTime()) fmt.Println(fi.Mode()) } fmt.Println("") fmt.Println(err) 5、TempDir
content := []byte("temporary file‘s content") dir,err := ioutil.TempDir("/home/user","example") if err != nil { log.Fatal(err) } defer os.RemoveAll(dir) // clean up tmpfn := filepath.Join(dir,"tmpfile") if err := ioutil.WriteFile(tmpfn,content,0666); err != nil { log.Fatal(err) } 6、TempFile
content := []byte("temporary file‘s content") tmpfile,err := ioutil.TempFile("/home/user","example") if err != nil { log.Fatal(err) } defer os.Remove(tmpfile.Name()) // clean up if _,err := tmpfile.Write(content); err != nil { log.Fatal(err) } if err := tmpfile.Close(); err != nil { log.Fatal(err) } 7、Discard
a := strings.NewReader("hello") p := make([]byte,20) io.Copy(ioutil.Discard,a) ioutil.Discard.Write(p) fmt.Println(p) //[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 8、NopCloser
s := strings.NewReader("hello world!") r := ioutil.NopCloser(s) r.Close() p := make([]byte,10) r.Read(p) fmt.Println(string(p)) //hello worl 四、bytes1、bytes简介bytes包提供了对字节切片进行读写操作的一系列函数。?字节切片处理的函数比较多,分为基本处理函数、比较函数、后缀检查函数、索引函数、分割函数、大小写处理函数和子切片处理函数等。 2、基本函数
package main import ( "fmt" "bytes" ) func main() { //Contains b := []byte("hello") //字符串强转为byte切片 sublice1 := []byte("h") sublice2 := []byte("l") fmt.Println(bytes.Contains(b,sublice1))// true fmt.Println(bytes.Contains(b,sublice2))// false //Count s := []byte("hello world") sep1 := []byte("ll") sep2 := []byte("l") sep3 := []byte("o") fmt.Println(bytes.Count(s,sep1))// 1 fmt.Println(bytes.Count(s,sep2))// 3 fmt.Println(bytes.Count(s,sep3))// 2 //Repeat b = []byte("hello world") fmt.Println(string(bytes.Repeat(b,1)))// hello world fmt.Println(string(bytes.Repeat(b,2)))// hello worldhello world //Replace s = []byte("hello,world") old := []byte("o") news := []byte("ee") fmt.Println(string(bytes.Replace(s,news,0)))//hello,world fmt.Println(string(bytes.Replace(s,1)))//hellee,2)))//hellee,weerld fmt.Println(string(bytes.Replace(s,-1)))//hellee,weerld //Runes s = []byte("你好世界") r := bytes.Runes(s) fmt.Println("转换前字符串的长度: ",len(s))//12 fmt.Println("转换后字符串的长度: ",len(r))//4 //Join ss := [][]byte{[]byte("你好"),[]byte("世界")} sep4 := []byte(",") fmt.Println(string(bytes.Join(ss,sep4)))//你好,世界 sep5 := []byte("#") fmt.Println(string(bytes.Join(ss,sep5)))//你好#世界 } 3、比较函数
package main import ( "fmt" "bytes" ) func main() { //Compare a := []byte("hello,go") b := []byte("hello,world") fmt.Println(bytes.Compare(a,b))//-1 b =[]byte("hello,c") fmt.Println(bytes.Compare(a,b))//1 b =[]byte("hello,World") fmt.Println(bytes.Compare(a,b))//1 小写字母大于大写字母 b =[]byte("b") fmt.Println(bytes.Compare(a,b))//-1 从第一个字节开始比较,如果相同再比较长度 //Equal a = []byte("abc") b = []byte("ABC") fmt.Println(bytes.Equal(a,b))//false fmt.Println(bytes.Equal(a,nil))//false b = []byte("abc") fmt.Println(bytes.Equal(a,b))//true //EqualFold a = []byte("abc") b = []byte("ABC") fmt.Println(bytes.EqualFold(a,b))//true } 4、前后缀检查
package main import ( "fmt" "bytes" ) func main() { //HasPrefix s := []byte("test_Hello.txt") prefix := []byte("test") fmt.Println(bytes.HasPrefix(s,prefix))//true prefix = []byte("Test") fmt.Println(bytes.HasPrefix(s,prefix))//false //HashSuffix suffix := []byte("txt") fmt.Println(bytes.HasSuffix(s,suffix))//true } 5、位置索引字节切片位置索引函数共有8个,Index()、IndexAny()、IndexByte()、IndexFunc()、IndexRune()、LastIndex()、LastIndexAny()和LastIndexFunc()。 package main import ( "fmt" "bytes" ) func main() { //Index a := []byte("hello,world") fmt.Println(bytes.Index(a,[]byte("o")))//4 fmt.Println(bytes.Index(a,[]byte("ll")))//2 fmt.Println(bytes.Index(a,[]byte("w")))//6 //IndexAny fmt.Println(bytes.IndexAny(a,"h"))//0 fmt.Println(bytes.IndexAny(a,"l"))//2 //IndexByte s := []byte("hello,world") var ch byte = ‘w‘ fmt.Println(bytes.IndexByte(s,ch))//6 //IndexFunc,可以接收匿名函数 fmt.Println(bytes.IndexFunc(s,func (a rune)bool{ if a == ‘o‘{ return true }else{ return false } }))//4 //IndexRune fmt.Println(bytes.IndexRune(s,‘e‘))//1 fmt.Println(bytes.IndexRune(s,‘a‘))//-1 //LastIndex fmt.Println(bytes.LastIndex(s,[]byte("g")))//-1 fmt.Println(bytes.LastIndex(s,[]byte("e")))//1 fmt.Println(bytes.LastIndex(s,[]byte("o")))//7 //LastIndexAny fmt.Println(bytes.LastIndexAny(s,"world"))//10 fmt.Println(bytes.LastIndexAny(s,"l"))//9 fmt.Println(bytes.LastIndexAny(s,"d"))//10 //LastIndexFunc fmt.Println(bytes.LastIndexFunc(s,func(r rune)bool{ if r==‘d‘{ return true }else { return false } }))//10 } 6、分割函数字节切片分割函数共有6个,Fields(),FieldsFunc(),Split(),SplitN(),? package main import ( "fmt" "bytes" ) func main() { //Fields,返回的是2维切片 s := []byte("hello world") for _,v := range bytes.Fields(s){ //遍历获取1维切片,再强转为字符串 fmt.Print(string(v)+",") // hello,world,} fmt.Println() //FieldsFunc,返回是2维切片,接收匿名函数 s = []byte("hello,world") for _,v := range bytes.FieldsFunc(s,func(r rune)bool{ if r == ‘,‘{ return true //按照空白字符分割 }else{ return false } }){ fmt.Print(string(v)+",")// hello,} fmt.Println() //Split s = []byte("天山老妖") for _,v := range bytes.Split(s,[]byte("山")){ fmt.Print(string(v)+",")//天,老妖,} fmt.Println() for _,nil){ fmt.Print(string(v)+",山,老,妖,} fmt.Println() //SplitAfter for _,v := range bytes.SplitAfter(s,")//天山,} fmt.Println() //SplitAfterN s = []byte("hello,hello,go") for _,v := range bytes.SplitAfterN(s,[]byte(","),0){ fmt.Print(string(v)+",") //什么都不输出 } fmt.Println() for _,4){ fmt.Print(string(v))//hello,go } fmt.Println() for _,[]byte(""),-1){ fmt.Print(string(v))//hello,go } fmt.Println() //SplitN s = []byte("hello,v := range bytes.SplitN(s,[]byte("he"),") // } fmt.Println() for _,[]byte("o"),3){ fmt.Print(string(v) + ",")//hell,w,rld,[]byte("ll"),-1){ fmt.Print(string(v)+",")//he,o,} } 7、大小写处理函数共有7个函数,Title(),ToTitle(),ToTitleSpecial(),ToLower(),ToLowerSpecial(),ToUpper()?和ToUpperSpecial()。 package main import ( "fmt" "bytes" "unicode" ) func main() { s := []byte("hello,go") fmt.Println(string(bytes.Title(s)))// Hello,Go fmt.Println(string(bytes.ToTitle(s)))// HELLO,GO fmt.Println(string(bytes.ToTitleSpecial(unicode.AzeriCase,s)))// HELLO,GO s = []byte("Hello,Go") fmt.Println(string(bytes.ToLower(s)))// hello,go fmt.Println(string(bytes.ToLowerSpecial(unicode.AzeriCase,s)))// hello,go s = []byte("Hello,Go") fmt.Println(string(bytes.ToUpper(s)))// HELLO,GO fmt.Println(string(bytes.ToUpperSpecial(unicode.AzeriCase,GO } 8、子字节切片处理函数子字节切片处理函数共有9个,Trim(),TrimFunc(),TrimLeft(),TrimLeftFunc(),TrimRight(),TrimRightFunc(),TrimSpace(),TrimPrefix()和TrimSuffix()。 package main import ( "fmt" "bytes" ) func main() { //Trim s := []byte(" Hello,Go ") fmt.Println(string(bytes.Trim(s," ")))// Hello,Go //TrimFunc s = []byte("hello world") fmt.Println(string(bytes.TrimFunc(s,func(r rune)bool{ if r==‘h‘ || r==‘d‘{ return true }else{ return false } }))) //ello worl s = []byte("hello,worldo") fmt.Println(string(bytes.TrimFunc(s,func(r rune)bool{ if r==‘h‘ || r==‘o‘{ return true }else{ return false } }))) // ello,world s = []byte("hello,world") fmt.Println(string(bytes.TrimFunc(s,func(r rune)bool{ if r==‘h‘ && r==‘o‘{ return true }else{ return false } }))) // hello,world //TrimLeft fmt.Println(string(bytes.TrimLeft(s,"h")))// ello,world fmt.Println(string(bytes.TrimLeft(s,"l")))// hello,world //TrimLeftFunc fmt.Println(string(bytes.TrimLeftFunc(s,func(r rune)bool{ if r == ‘h‘ || r==‘l‘{ return true }else{ return false } }))) // ello,world //TrimRight fmt.Println(string(bytes.TrimRight(s,"d")))// hello,worl //TrimRightFunc fmt.Println(string(bytes.TrimRightFunc(s,func(r rune)bool{ if r == ‘d‘{ return true }else{ return false } })))// hello,worl //TrimSpace s = []byte(" hello world ") fmt.Println(string(bytes.TrimSpace(s)))// hello world //TrimPrefix s = []byte("test_Go") fmt.Println(string(bytes.TrimPrefix(s,[]byte("test_"))))// Go fmt.Println(string(bytes.TrimPrefix(s,[]byte("Test"))))// test_Go //TrimSuffix s = []byte("hello.go") fmt.Println(string(bytes.TrimSuffix(s,[]byte(".go"))))// hello fmt.Println(string(bytes.TrimSuffix(s,[]byte(".cpp"))))// hello.go } 五、path1、path简介path实现了对斜杠分隔的路径进行操作的函数。 2、path常用接口
package main import ( "fmt" "path" ) func main() { pt := "~/GoLang" // 判断是否是一个绝对路径 is_abs := path.IsAbs(pt) fmt.Println(is_abs) // false // 将路径分割为路径和文件名 pf := "/home/user/hello.go" dir,file := path.Split(pf) fmt.Println(dir,file) // /home/user/ hello.go // 将多个字符串合并为一个路径 dir_join := path.Join("usr","local","bin") fmt.Println(dir_join) // usr/local/bin // 返回路径中扩展 file_ext := path.Ext(pf) fmt.Println(file_ext) // .go // 返回路径的最后一个元素 dir_base := path.Base(pf) fmt.Println(dir_base) // hello.go // 返回路径中目录部分 dir = path.Dir(pf) fmt.Println(dir) // /home/user // 返回同目录的最短路径 dir_a := "/usr/../opt/../home/user" fmt.Println(path.Clean(dir_a)) // /home/user // 正则是否匹配路径 is_match,err := path.Match("*.xml","a.xml") fmt.Println(is_match,err) // true <nil> } 3、filepath常用接口
package main import ( "fmt" "os" "path/filepath" ) // 打印路径名称 func pathName(path string,info os.FileInfo,err error) error { if err != nil { return err } else { fmt.Println(path) } return nil } func main() { // 预定义变量 fmt.Println(string(filepath.Separator),string(filepath.ListSeparator)) // 返回path 相对当前路径的绝对路径 dir := "/home/user/hello.go" real_dir,err := filepath.Abs(dir) fmt.Println(real_dir,err) // 返回path 的最短路径 dir = "/usr/../etc/../tmp" clear_dir := filepath.Clean(dir) fmt.Println(clear_dir) // /tmp // 返回targpath 相对 basepath路径 basepath,targpath := "/usr/local","/usr/local/go/bin" rel_dir,err := filepath.Rel(basepath,targpath) fmt.Println(rel_dir,err) // go/bin <nil> // 返回软链指向的路径 symlink := "/usr/local" real_dir,err = filepath.EvalSymlinks(symlink) fmt.Println(real_dir,err) // /usr/local <nil> // 返回路径最前面的卷名 root := "/usr/local/go" vol := filepath.VolumeName(root) fmt.Println(vol) // ‘‘ // 路径分隔符替换为 `/` slash_dir := filepath.ToSlash(root) fmt.Println(slash_dir) // /usr/local/go // `/` 替换为路径分隔符 from_slash := filepath.FromSlash(slash_dir) fmt.Println(from_slash) // /usr/local/go // 分隔环境变量里面的路径 env_path := "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/go/bin" env_slice := filepath.SplitList(env_path) for k,v := range env_slice { fmt.Println(k,v) } // 0 /usr/local/bin // 1 /usr/bin // 2 /bin // 3 /usr/sbin // 4 /sbin // 5 /opt/X11/bin // 6 /usr/local/go/bin // 遍历 root 目录下的文件树,并调用 walkFn root_dir,err := os.Getwd() err = filepath.Walk(root_dir,pathName) fmt.Println(err) } 4、目录遍历
func Walk(root string,walkFn WalkFunc) error { //获取root的描述信息 info,err := os.Lstat(root) if err != nil { //如果获取描述信息发生错误,返回err由定义的walkFn函数处理 err = walkFn(root,nil,err) } else { //调用walk(root,info,walkFn)函数进行递归遍历root err = walk(root,walkFn) } if err == SkipDir { return nil } return err } Walk方法会遍历root下的所有文件(包含root)并对每一个目录和文件都调用walkFunc方法。在访问文件和目录时发生的错误都会通过error参数传递给WalkFunc方法。文件是按照词法顺序进行遍历的,通常让输出更漂亮,但也会导致处理非常大的目录时效率会降低。另外,Walk函数不会遍历符号链接。 func walk(path string,walkFn WalkFunc) error { //调用定义的walkFn自定义函数处理 err := walkFn(path,nil) if err != nil { //返回错误,且该目录可以跳过 if info.IsDir() && err == SkipDir { return nil } return err } //如果是文件,则遍历下一个 if !info.IsDir() { return nil } //读取该path下的所有目录和文件 names,err := readDirNames(path) if err != nil { //发生错误,调用自定义函数处理 return walkFn(path,err) } //遍历文件和目录列表 for _,name := range names { //路径path/name filename := Join(path,name) //获取该文件或者目录信息 fileInfo,err := lstat(filename) if err != nil { //发生错误,调用自定义函数处理 if err := walkFn(filename,fileInfo,err); err != nil && err != SkipDir { return err } } else { //这里递归调用,获取root下各级文件和目录信息,在自定义函数walkFn里做处理 err = walk(filename,walkFn) if err != nil { //遍历文件发生错误或者目录发生错误且不能跳过,则返回err if !fileInfo.IsDir() || err != SkipDir { return err } } } } return nil } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |