读取
读取-只读模式
此模式仅可读取文件
// 只读打开f, err := os.Open("./book.html")if err != nil {fmt.Println(err.Error())}// 延迟关闭文件句柄defer f.Close()readFile := func() []byte {// 读取文件内容var content []bytetmp := make([]byte, 128) // 临时变量for {// 读取值到临时变量// byteNum 读取到的字节数byteNum, err := f.Read(tmp)if err == io.EOF {fmt.Println("文件读取结束")break}// 这里如果使用tmp[]..., 可以会写入零值数据(因为临时存储区大小和文件结尾可能不一致)content = append(content, tmp[:byteNum]...)}return content}fmt.Printf("文件内容: \n%s\n", readFile())
虽然叫只读模式,但是方法内调用的是OpenFile(name, O_RDONLY, 0),详见👇🏻
�
读取-通用模式
此模式是可自由设置执行的操作及文件权限等
常用flag:
| 变量 | 作用 |
|---|---|
| os.O_RDONLY | 只读模式 |
| os.O_WRONLY | 只写模式 |
| os.O_RDWR | 读和写模式 |
| os.O_APPEND | 插入模式 |
| os.O_CREATE | 创建模式(未找到文件会创建) |
| os.O_SYNC | 同步IO模式(阻塞模式) |
| os.O_EXCL | 与O_CREATE一起使用,文件不能存在 |
| 多模式 | os.O_WRONLY | os.O_CREATE |
// filename 文件名// flag: 执行的操作(os/file.go 73行定义)// filemode: 文件权限(仅在linux及类linux平台使用, os/types.go 35行定义 )f, err := os.OpenFile("./deme.pu", os.O_RDONLY, os.ModePerm)if err != nil {fmt.Println(err.Error())}defer f.Close()fmt.Printf("%s\n", readFile(f))
使用bufio读取文件
f, err := os.Open("./demo.txt")if err != nil {fmt.Println(err.Error())}defer f.Close()reader := bufio.NewReader(f)for {line, isPrefix, err := reader.ReadLine()if err == io.EOF {fmt.Println("文件读完了")break}if err != nil {fmt.Printf("文件读取失败%s\n", err.Error())return}fmt.Println(string(line), isPrefix)}
bufio是在file的基础上封装了一层API,并且支持更多功能,比如上面代码会删除换行符
使用ioutil读取整个文件
f, err := ioutil.ReadFile("./test.txt")if err != nil {log.Fatalln(err.Error())}fmt.Println(string(f))
ioutil.ReadFile()方法可以将整个文件读取至变量,建议在读取小文件时使用(大文件容易造成内存泄露)
写入
f, _ := os.OpenFile("./deme.txt", os.O_WRONLY|os.O_CREATE, os.ModePerm)defer f.Close()byteNum, _ := f.Write([]byte("你好"))fmt.Printf("write byte %d\n",byteNum)
以上代码使用os包的OpenFile函数,通过设置写入和创建flag来在文件没有时创建并写入文件
f, _ := os.OpenFile("./deme.txt", os.O_WRONLY|os.O_APPEND, os.ModePerm)defer f.Close()byteNum, _ := f.Write([]byte("你好"))fmt.Printf("write byte %d\n",byteNum)
使用bufio.NewWriter写入
f, _ := os.OpenFile("./demo.txt", os.O_WRONLY, os.ModePerm)defer f.Close()bfw := bufio.NewWriter(f)bfw.Write([]byte("hello\n"))bfw.WriteString("你好\n")bfw.Flush()
使用bufio可以将写入缓存中,然后通过Flush方法写入文件
使用ioutil.WriteFile写入
err := ioutil.WriteFile("./tmp.txt", []byte("world"), os.ModePerm)if err != nil {log.Fatalf("写入失败: %s", err.Error())}
使用ioutil同样可以写入文件,并且在文件不存在时帮你创建
使用ioutil.TmpDir创建临时文件
name, _ := ioutil.TempDir("./tmp/", "dong_")defer func(name string) {err := os.Remove(name)if err != nil {log.Fatalln("删除失败")} else {log.Println("删除成功")}}(name)fmt.Println(name)time.Sleep(10 * time.Second)
临时目录可以临时存储一些文件,并在不再使用后删除
练习
写个cp命令
var srcFile stringvar dstPath string_, err := fmt.Scan(&srcFile, &dstPath)if err != nil {log.Fatalln(err.Error())return}src, err := os.Open(srcFile)if err != nil {log.Fatalf("Open file failed : %s", err.Error())}defer src.Close()dst, err := os.OpenFile(dstPath+src.Name(), os.O_CREATE|os.O_EXCL|os.O_WRONLY, os.ModePerm)if err != nil {log.Fatalln(err.Error())}_, err = io.Copy(dst, src)if err != nil {log.Fatalf("Copy error %s", err.Error())}
通过fmt.Scan获取命令行参数,通过io.Copy方法将流拷贝至新文件,因为os.OpenFile实现了io.Writer和io.Reader接口
