创建和删除目录
1 os.Mkdir("file", os.ModePerm) 2 os.MkdirAll("file2/sub1/sub2", os.ModePerm) 3 err := os.Remove("file2/sub1") // cann't remove 4 if err != nil { 5 fmt.Println(err) 6 } 7 os.RemoveAll("file2") 8 os.Remove("file")
linux中文件权限的表示
可读-可写-可执行表示为111,没有权限使用0
分组:自己-同组用户-其他用户,每组3位数,如110 110 100即664,表示自己可读写,同组用户可读写,其他用户可读。
创建并写文件
1 fout, err := os.Create("t1.txt") 2 if err != nil { 3 fmt.Println(err) 4 return 5 } 6 defer fout.Close() 7 8 for i := 0; i < 10; i++ { 9 fout.WriteString("just 测试 string.\r\n") 10 fout.Write([]byte("just 测试 []byte.\r\n")) 11 }
打开并读文件
1 f, err := os.Open("t1.txt") 2 if err != nil { 3 fmt.Println(err) 4 return 5 } 6 defer f.Close() 7 8 buf := make([]byte, 1024) 9 for { 10 n, _ := f.Read(buf) 11 if n == 0 { 12 break 13 } 14 os.Stdout.Write(buf[:n]) 15 }
也可以使用 ioutil.ReadAll(f),它会把整个文件都读到内存中。
按行读取文件
1func FileRead(filePath string) (err error) { 2 file, err := os.OpenFile(filePath, os.O_RDONLY, os.ModePerm) 3 if err != nil { 4 return 5 } 6 defer file.Close() 7 8 reader := bufio.NewReader(file) 9 var ( 10 line string 11 lineCount int 12 ) 13 for err == nil { 14 line, err = reader.ReadString('\n') 15 line = strings.TrimSpace(line) // line包含换行符 16 if line == "" { 17 continue 18 } 19 lineCount++ 20 if lineCount > 10 { 21 break 22 } 23 fmt.Println(lineCount, line) 24 } 25 if err == io.EOF { 26 err = nil 27 } 28 return 29}
使用bufio.NewScanner
1 input := bufio.NewScanner(f) 2 for input.Scan() { 3 counts[input.Text()]++ // input.Text()不包含换行符 4 } 5 6 7// readFromFile will read all lines from the given filename and write them to a 8// string array, if filename is empty readFromFile returns and empty string 9// array 10func readLinesFromFile(filename string) ([]string, error) { 11 if filename == "" { 12 return nil, nil 13 } 14 15 file, err := os.Open(filename) 16 if err != nil { 17 return nil, err 18 } 19 defer file.Close() 20 21 var lines []string 22 23 scanner := bufio.NewScanner(file) 24 for scanner.Scan() { 25 lines = append(lines, scanner.Text()) 26 } 27 28 if err := scanner.Err(); err != nil { 29 return nil, err 30 } 31 32 return lines, nil 33}
删除文件
删除文件和删除目录是同一个方法
1 err := os.Remove("t1.txt") 2 if err != nil { 3 fmt.Println(err) 4 } else { 5 fmt.Println("removed.") 6 }
删除目录时要求目录是空的。
覆盖式写文件(不存在时创建)
1 file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) 2 if err != nil { 3 return 4 } 5 defer file.Close() 6 7 _, err = file.Write(data)
遍历目录
遍历所有后代文件或目录
1 filepath.Walk("/a/b/c", func(path string, info os.FileInfo, err error) error { 2 // do something... 3 return nil 4 })
path是文件的全路径
跳过目录
return filepath.SkipDir
遍历子文件或目录
1file, _ := os.Open(path) 2children, _ := file.Readdir(-1)
或者使用ioutil.ReadDir()
以树形显示目录树
1func WalkSubDir() (t *tree.TreeNode) { 2 root := "/a/b/c" 3 t = tree.NewTreeNode(nil, root) 4 5 walkDirToTree(t, root) 6 return t 7} 8 9func walkDirToTree(t *tree.TreeNode, path string) { 10 file, _ := os.Open(path) 11 fileInfo, _ := file.Stat() 12 node, _ := t.AppendChild(fileInfo.Name()) 13 14 // 文件 15 if !fileInfo.IsDir() { 16 return 17 } 18 19 // 目录 20 children, _ := file.Readdir(-1) 21 for _, child := range children { 22 walkDirToTree(node, filepath.Join(path, child.Name())) 23 } 24}
使用正则搜索文件
1 dir := "/a" 2 files, err := filepath.Glob(dir + "/*.md") 3 if err != nil { 4 panic(err) 5 } 6 7 for _, d := range files { 8 fmt.Printf("match %10s \n", d) 9 }
输出示例:
match /a/a.md
可用的正则:
1pattern: 2 { term } 3term: 4 '*' matches any sequence of non-Separator characters 5 '?' matches any single non-Separator character 6 '[' [ '^' ] { character-range } ']' 7 character class (must be non-empty) 8 c matches character c (c != '*', '?', '\\', '[') 9 '\\' c matches character c 10 11character-range: 12 c matches character c (c != '\\', '-', ']') 13 '\\' c matches character c 14 lo '-' hi matches character c for lo <= c <= hi
查看文档和test文件了解更多。
当前程序运行的目录
1 workPath, _ = os.Getwd() 2 workPath, _ = filepath.Abs(workPath) 3 AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
- 摘自beego
- os.Args[0] 是运行文件的全路径
- workPath 和 AppPath 应该是一样的,不一样的情况还不知道是怎么样的?
判断文件是否存在
1func FileExists(name string) bool { 2 if _, err := os.Stat(name); err != nil { 3 if os.IsNotExist(err) { 4 return false 5 } 6 } 7 return true 8}
- 摘自beego
- os.IsNotExist(err) 可判断err是不是表示不存在
- 与之相反的是:os.IsExist(err)
- 也可以判断目录是否存在
以列表显示目录树,可自定义根节点名称
1func GetHugoContentDirList() (list []string) { 2 root, err := os.Open("D:/work/hugo/mysite/content") 3 if err != nil { 4 return 5 } 6 list = append(list, "root") 7 children := getChildren("root", root) 8 list = append(list, children...) 9 return 10} 11 12func getChildren(prefix string, parent *os.File) (children []string) { 13 cFiles, err := parent.Readdir(-1) 14 if err != nil { 15 return 16 } 17 18 parentAbsPath, err := filepath.Abs(parent.Name()) 19 if err != nil { 20 fmt.Println(err) 21 return 22 } 23 24 for _, c := range cFiles { 25 fullPath := prefix + "/" + c.Name() 26 children = append(children, fullPath) 27 if c.IsDir() { 28 cFile, err := os.Open(filepath.Join(parentAbsPath, c.Name())) 29 if err != nil { 30 fmt.Println(err, c.Name()) 31 continue 32 } 33 subChildren := getChildren(fullPath, cFile) 34 children = append(children, subChildren...) 35 } 36 } 37 return 38}
输出示例:
[root root/about.md root/post root/post/first.md root/post/second.md root/post/THREE.md]
复制文件
1// copyFile creates dst from src, preserving file attributes and timestamps. 2func copyFile(dst, src string) error { 3 fi, err := os.Stat(src) 4 if err != nil { 5 return err 6 } 7 8 fsrc, err := os.Open(src) 9 if err != nil { 10 return err 11 } 12 13 if err = os.MkdirAll(filepath.Dir(dst), 0755); err != nil { 14 fmt.Printf("MkdirAll(%v)\n", filepath.Dir(dst)) 15 return err 16 } 17 18 fdst, err := os.Create(dst) 19 if err != nil { 20 return err 21 } 22 23 if _, err = io.Copy(fdst, fsrc); err != nil { 24 return err 25 } 26 27 if err == nil { 28 err = fsrc.Close() 29 } 30 31 if err == nil { 32 err = fdst.Close() 33 } 34 35 if err == nil { 36 err = os.Chmod(dst, fi.Mode()) 37 } 38 39 if err == nil { 40 err = os.Chtimes(dst, fi.ModTime(), fi.ModTime()) 41 } 42 43 return nil 44}