Go提供了os和 ioutils包来对文件和文件夹进行操作,值得高兴的是,它们是跨平台的,无需对操作系统做过多考虑。

实践

1.建立 dirs.go :

package filedirs

import (
    "errors"
    "io"
    "os"
)

// 操纵文件和目录
func Operate() error {
    // 文件权限0755类似于你在命令行中使用的chown,
    // 这将创建一个目录 /tmp/example,
    // 你也可以使用绝对路径而不是相对路径
    if err := os.Mkdir("example_dir", os.FileMode(0755)); err != nil {
        return err
    }

    // 跳转到 /tmp 目录
    if err := os.Chdir("example_dir"); err != nil {
        return err
    }

    // f是一个通用的文件对象 它还实现了多个接口,并且如果在打开时设置了正确的方式,则可以用作读取器或写入器
    f, err := os.Create("test.txt")
    if err != nil {
        return err
    }

    // 向文件写入长度已知的数据 并确认写入成功
    value := []byte("hello\n")
    count, err := f.Write(value)
    if err != nil {
        return err
    }
    if count != len(value) {
        return errors.New("incorrect length returned from write")
    }

    if err := f.Close(); err != nil {
        return err
    }

    // 读取文件
    f, err = os.Open("test.txt")
    if err != nil {
        return err
    }

    io.Copy(os.Stdout, f)

    if err := f.Close(); err != nil {
        return err
    }

    // 跳转到 /tmp 文件夹
    if err := os.Chdir(".."); err != nil {
        return err
    }

    // 删除建立的文件夹
    // os.RemoveAll如果传递了错误的文件夹路径会返回错误
    if err := os.RemoveAll("example_dir"); err != nil {
        return err
    }

    return nil
}

2.建立bytes.go:

package filedirs

import (
    "bytes"
    "io"
    "os"
    "strings"
)

// 读取并转换为大写后复制内容到目标文件
func Capitalizer(f1 *os.File, f2 *os.File) error {
    if _, err := f1.Seek(0, 0); err != nil {
        return err
    }

    var tmp = new(bytes.Buffer)

    if _, err := io.Copy(tmp, f1); err != nil {
        return err
    }

    s := strings.ToUpper(tmp.String())

    if _, err := io.Copy(f2, strings.NewReader(s)); err != nil {
        return err
    }
    return nil
}

// 建立两个文件 将其中一个的内容转换为大写复制给另一个
func CapitalizerExample() error {
    f1, err := os.Create("file1.txt")
    if err != nil {
        return err
    }

    if _, err := f1.Write([]byte(` this file contains a number of words and new lines`)); err != nil {
        return err
    }

    f2, err := os.Create("file2.txt")
    if err != nil {
        return err
    }

    if err := Capitalizer(f1, f2); err != nil {
        return err
    }

    if err := os.Remove("file1.txt"); err != nil {
        return err
    }

    if err := os.Remove("file2.txt"); err != nil {
        return err
    }

    return nil
}

3.建立main.go:

package main

import "github.com/agtorre/go-cookbook/chapter1/filedirs"

func main() {
    if err := filedirs.Operate(); err != nil {
        panic(err)
    }

    if err := filedirs.CapitalizerExample(); err != nil {
        panic(err)
    }
}

4.运行main.go,这会输出:

hello

示例在运行中会分别建立file1.txt和file2.txt然后删掉,file1.txt中包含:

this file contains a number of words and new lines

file2.txt中包含:

THIS FILE CONTAINS A NUMBER OF WORDS AND NEW LINES

说明

如果你熟悉Unix下的文件系统,那么Go的os包一定看起来很亲切。你可以使用该包进行基本的文件操作——例如查看文件状态,修改文件权限,操作文件及文件夹等。在示例中我们对目录和文件进行了操作,并在操作结束后对其进行删除。

操作文件对象与操作内存中的流数据非常相似。os.File还提供了许多便利的函数,例如Chown,Stat和Truncate。 想要熟悉os.File的各种函数最简单方法就是使用它们。在所有的示例中,我们都会小心的清理程序中额外产生的临时文件,在日常工作中这也是个很好的习惯。

当你读取文件并将其存储在File结构之后,就可以轻松地将其传递给前面讨论的多个 I/O 接口。在之前示例中,我们看到的对缓冲区和内存数据的操作都可以直接替换为文件对象。因此,对于诸如将日志写入stderr以及对单个写入调用同时将其写入文件之类的操作会很有用。

最后编辑: kuteng  文档更新时间: 2021-01-03 15:03   作者:kuteng