go笔记

Wesley13
• 阅读 306

创建和删除目录

    os.Mkdir("file", os.ModePerm)
    os.MkdirAll("file2/sub1/sub2", os.ModePerm)
    err := os.Remove("file2/sub1") // cann't remove
    if err != nil {
        fmt.Println(err)
    }
    os.RemoveAll("file2")
    os.Remove("file")

linux中文件权限的表示

可读-可写-可执行表示为111,没有权限使用0

分组:自己-同组用户-其他用户,每组3位数,如110 110 100即664,表示自己可读写,同组用户可读写,其他用户可读。

创建并写文件

    fout, err := os.Create("t1.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer fout.Close()

    for i := 0; i < 10; i++ {
        fout.WriteString("just 测试 string.\r\n")
        fout.Write([]byte("just 测试 []byte.\r\n"))
    }

打开并读文件

    f, err := os.Open("t1.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()

    buf := make([]byte, 1024)
    for {
        n, _ := f.Read(buf)
        if n == 0 {
            break
        }
        os.Stdout.Write(buf[:n])
    }

也可以使用 ioutil.ReadAll(f),它会把整个文件都读到内存中。

按行读取文件

func FileRead(filePath string) (err error) {
    file, err := os.OpenFile(filePath, os.O_RDONLY, os.ModePerm)
    if err != nil {
        return
    }
    defer file.Close()

    reader := bufio.NewReader(file)
    var (
        line      string
        lineCount int
    )
    for err == nil {
        line, err = reader.ReadString('\n')
        line = strings.TrimSpace(line) // line包含换行符
        if line == "" {
            continue
        }
        lineCount++
        if lineCount > 10 {
            break
        }
        fmt.Println(lineCount, line)
    }
    if err == io.EOF {
        err = nil
    }
    return
}

使用bufio.NewScanner

    input := bufio.NewScanner(f)
    for input.Scan() {
        counts[input.Text()]++ // input.Text()不包含换行符
    }


// readFromFile will read all lines from the given filename and write them to a
// string array, if filename is empty readFromFile returns and empty string
// array
func readLinesFromFile(filename string) ([]string, error) {
    if filename == "" {
        return nil, nil
    }

    file, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    var lines []string

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        lines = append(lines, scanner.Text())
    }

    if err := scanner.Err(); err != nil {
        return nil, err
    }

    return lines, nil
}

删除文件

删除文件和删除目录是同一个方法

    err := os.Remove("t1.txt")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("removed.")
    }

删除目录时要求目录是空的。

覆盖式写文件(不存在时创建)

    file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
    if err != nil {
        return
    }
    defer file.Close()

    _, err = file.Write(data)

遍历目录

遍历所有后代文件或目录

    filepath.Walk("/a/b/c", func(path string, info os.FileInfo, err error) error {
        // do something...
        return nil
    })

path是文件的全路径

跳过目录

return filepath.SkipDir

遍历子文件或目录

file, _ := os.Open(path)
children, _ := file.Readdir(-1)

或者使用ioutil.ReadDir()

以树形显示目录树

func WalkSubDir() (t *tree.TreeNode) {
    root := "/a/b/c"
    t = tree.NewTreeNode(nil, root)

    walkDirToTree(t, root)
    return t
}

func walkDirToTree(t *tree.TreeNode, path string) {
    file, _ := os.Open(path)
    fileInfo, _ := file.Stat()
    node, _ := t.AppendChild(fileInfo.Name())

    // 文件
    if !fileInfo.IsDir() {
        return
    }

    // 目录
    children, _ := file.Readdir(-1)
    for _, child := range children {
        walkDirToTree(node, filepath.Join(path, child.Name()))
    }
}

使用正则搜索文件

    dir := "/a"
    files, err := filepath.Glob(dir + "/*.md")
    if err != nil {
        panic(err)
    }

    for _, d := range files {
        fmt.Printf("match %10s \n", d)
    }

输出示例:

match /a/a.md 

可用的正则:

pattern:
    { term }
term:
    '*'         matches any sequence of non-Separator characters
    '?'         matches any single non-Separator character
    '[' [ '^' ] { character-range } ']'
                character class (must be non-empty)
    c           matches character c (c != '*', '?', '\\', '[')
    '\\' c      matches character c

character-range:
    c           matches character c (c != '\\', '-', ']')
    '\\' c      matches character c
    lo '-' hi   matches character c for lo <= c <= hi

查看文档和test文件了解更多。

当前程序运行的目录

    workPath, _ = os.Getwd()
    workPath, _ = filepath.Abs(workPath)
    AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
  • 摘自beego
  • os.Args[0] 是运行文件的全路径
  • workPath 和 AppPath 应该是一样的,不一样的情况还不知道是怎么样的?

判断文件是否存在

func FileExists(name string) bool {
    if _, err := os.Stat(name); err != nil {
        if os.IsNotExist(err) {
            return false
        }
    }
    return true
}
  • 摘自beego
  • os.IsNotExist(err) 可判断err是不是表示不存在
  • 与之相反的是:os.IsExist(err)
  • 也可以判断目录是否存在

以列表显示目录树,可自定义根节点名称

func GetHugoContentDirList() (list []string) {
    root, err := os.Open("D:/work/hugo/mysite/content")
    if err != nil {
        return
    }
    list = append(list, "root")
    children := getChildren("root", root)
    list = append(list, children...)
    return
}

func getChildren(prefix string, parent *os.File) (children []string) {
    cFiles, err := parent.Readdir(-1)
    if err != nil {
        return
    }

    parentAbsPath, err := filepath.Abs(parent.Name())
    if err != nil {
        fmt.Println(err)
        return
    }

    for _, c := range cFiles {
        fullPath := prefix + "/" + c.Name()
        children = append(children, fullPath)
        if c.IsDir() {
            cFile, err := os.Open(filepath.Join(parentAbsPath, c.Name()))
            if err != nil {
                fmt.Println(err, c.Name())
                continue
            }
            subChildren := getChildren(fullPath, cFile)
            children = append(children, subChildren...)
        }
    }
    return
}

输出示例:

[root root/about.md root/post root/post/first.md root/post/second.md root/post/THREE.md]

复制文件

// copyFile creates dst from src, preserving file attributes and timestamps.
func copyFile(dst, src string) error {
    fi, err := os.Stat(src)
    if err != nil {
        return err
    }

    fsrc, err := os.Open(src)
    if err != nil {
        return err
    }

    if err = os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
        fmt.Printf("MkdirAll(%v)\n", filepath.Dir(dst))
        return err
    }

    fdst, err := os.Create(dst)
    if err != nil {
        return err
    }

    if _, err = io.Copy(fdst, fsrc); err != nil {
        return err
    }

    if err == nil {
        err = fsrc.Close()
    }

    if err == nil {
        err = fdst.Close()
    }

    if err == nil {
        err = os.Chmod(dst, fi.Mode())
    }

    if err == nil {
        err = os.Chtimes(dst, fi.ModTime(), fi.ModTime())
    }

    return nil
}
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
2年前
Golang 读写文件
读文件funcReadFile_v1(filenamestring){var(errerrorcontentbyte)fileObj,err:os.Open(filename)iferr!nil{
Stella981 Stella981
2年前
Golang文件名命名规则
在golang源代码中,经常看到各种文件名,比如:bolt\_windows.go。下面对文件名命令规则的说明:1、平台区分文件名\_平台。例:file\_windows.go,file\_unix.go可选为:windows,unix,posix,plan9,darwin,bsd,linux,freebsd,nac
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Stella981 Stella981
2年前
Lua学习笔记
\TOC\Lua学习笔记(整理的runoob加自己的见解)注意事项Lua中变量没有预定义类型,每个变量可以包含任意类型的值,要用就直接赋值一种数据类型的值nil类型就nil一个值,表示变量是否被赋值,变量赋值成nil也表示删除变量使用Type(
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这