## 操作文件夹和文件 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以及对单个写入调用同时将其写入文件之类的操作会很有用。 * * * * 学识浅薄,错误在所难免。欢迎在群中就本书提出修改意见,以飨后来者,长风拜谢。 Golang中国(211938256) beego实战(258969317) Go实践(386056972)