22-文件操作

7 阅读3分钟

文件读写

  1. 文件是存储在外部介质上的数据集合 A. 文件分类: 文本文件和二进制文件 B. 文件存取方式: 随机存取和顺序存放

  2. 文件打开

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    // => 只读的方式打开文件
    file, err := os.Open("a.txt")
    if err != nil {
        fmt.Printf("open file failed %v\n", err)
        return
    }
    defer file.Close()//关闭文件
}
  1. 文件读取, file.Readfile.ReadAt. 读到文件末尾返回 io.EOF
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    // => 只读的方式打开文件
    file, err := os.Open("a.txt")
    if err != nil {
        fmt.Printf("open file failed %v\n", err)
        return
    }

    defer file.Close()//关闭文件

    var content []byte
    var buf[128]byte// 限制128字节

    for {
        n, err := file.Read(buf[:])// 一次最多只能读128个字节
        if err == io.EOF {//文件读取完了
            break
        }
        if err != nil {
            fmt.Println("read file", err)
            return
        }
        content = append(content, buf[:]...)
    }

    fmt.Println(string(content))
}
  1. bufio 原理
  • 缺点就是: 缓冲是存入内存的,一旦挂了,缓冲区的数据就丢失了
                                  当buff为空
程序(program)  <---   缓冲(buff) <----------------------- 文件file
      /|                          一次读取buff大小的内容      |
       |                                                    |
       |_____________________________________________________|
                    读取大于buff的内容

        写入小于buff的内容时                    当buff没有足够空间时
程序(program)  --->   缓冲(buff) -----------------------> 文件file
       |                        把缓冲区内容写入文件清空缓冲区  |\
       |                                                     |
       |_____________________________________________________|
                    大于buff直接写入文件

bufio 读文件

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func main() {
	file, err := os.Open("b.txt")

	if err != nil {
		fmt.Println("Error opening file:", err)
		return
	}

	defer file.Close()

	reader := bufio.NewReader(file) // 转成 buff

	// 循环的去读文件
	for {
		line, err := reader.ReadString('\n')
		// 读到文件末尾终止
		if err != nil {
			if err == io.EOF { // END of file
				break
			} else {
				fmt.Print("读文件错误:", err)
				return
			}
		} else {
			fmt.Print(line) // 打印每一行内容
		}
	}
}
  1. ioutil使用读取
package main

import (
    "io/ioutil"
    "fmt"
)

func main() {
    content, err := ioutil.ReadFile("a.tx")
    if err != nil {
        fmt.Println("read file failed, err:", err)
        return
    }

    fmt.Println(string(content))
}
  1. 读取gz压缩文件
package main

import (
    "io/ioutil"
    "compress/gzip"
    "bufio"
    "fmt"
    "os"
)

func main() {
    fName := "myFile.gz"
    file, err := os.Open(fName)

    if err != nil {
        fmt.Println("open file failed, err:", err)
        return
    }

    defer file.Close()
    fz, err:= gzip.NewReader(file)//读取并解压
    if err != nil {
        fmt.Println("gzip new reader failed, err:", err)
        return
    }

    var content []byte
    var buf [128]byte

    for {
        n, err := fz.Read(buf[:])
        if err == io.EOF {
            break
        }
        if err != nil {
            fmt.Println("gzip read failed, err:", err)
            return
        }
        content = append(content, buf[:n]...)
    }

    fmt.Println(string(content))
}

文件写入

os.OpenFile("output.dat", os.O_WRONLY | os.O_CREATE, 0666)

  • 第二参数: 文件打开模式:
  1. os.O_WRONLY: 只写
  2. os.O_CREATE: 没有文件时自动创建文件
  3. os.O_RDONLY: 只读
  4. os.O_RDWR: 读写
  5. os.O_TRUNC: 先清空
  6. os.O_APPEND: 追加
  7. os.O_
  • 第三参数: 权限控制
    • r -> 004 读
    • w -> 002 写
    • x -> 001
      • 6 = 4 + 2
    • 0666 -> 主人的权限、根文件主人在同一个用户群权限、其他人的权限
      • 所有人都有权限
      • 4=readable;2=writable;1=executable;6=4+2(可读+可写)

file.Write() -> 直接写入 file.WriteAt() -> 在指定位置写入 file.WriteString() -> 直接写入字符串

package main

import (
    "os"
    "bufio"
    "fmt"
    "io/ioutil"
)

// ioutil写入
func ioutilWrite() {
    str := "hello world"
    err := ioutil.WriteFile("file.txt", []byte(str), 0755)
    if err != nil {
        fmt.Println("read file failed, err:", err)
        return
    }
}

// bufio方式写入
func writeBufio() {
    file, err := os.OpenFile("b.txt", os.O_CREATE | os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("open file err", err)
        return
    }
    defer file.Close()

    write, err := bufio.NewWriter(file)
    if err != nil {
        fmt.Println("write file err", err)
        return
    }

    for i := 0; i < 10; i++ {
        write.WriteString("hello world!\n")
    }
    write.Flush()//清空缓存
}

func main() {
    file, err := os.OpenFile("./a.txt", os.O_CREATE | os.O_TRUNC | os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("open file failed, err", err)
        return
    }
    defer file.Close()
    str := "hello world"
    file.Write([]byte(str))
    file.WriteString(str)
}

拷贝文件

package main

import (
    "fmt"
    "io"
    "os"
)

// copy命令拷贝文件
func copyFile(dstName, srcName string)(written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
        fmt.Println("open file failed, err\n", err)
        return
    }
    defer src.Colse()
    dst, err := os.OpenFile(dstName, os.O_CREATE | os.O_WRONLY, 0644)
    if err != nil {
        fmt.Println("open file failed, err\n", err)
        return
    }

    defer dst.Colse()
    return io.Copy(dst, src)
}

// cat命令拷贝文件
func catFile(r *bufio.Reader) {
    for {
        buf, err := r.ReadBytes('\n')
        if err != nil {
            break
        }
        fmt.Fprintf(os.Stdout, "%s\n", buf)
    }
}

func main() {
    _, err := copyFile("a.txt", "b.txt")
    if err != nil {
        fmt.Println("copyFile failed, err\n", err)
        return
    }
    fmt.Println("copyFile succeeded")
}