当前位置: 首页 > 工具软件 > IOC-golang > 使用案例 >

golang IO操作

姬俊能
2023-12-01

golang IO操作



file句柄


os.Open(name string)方法以只读方式打开文件,os 包还提供了 os.OpenFile(name string, flag int, perm FileMode)方法,通过指定额外的 读写方式文件权限参数,使文件操作变得更为灵活。

其中,flag 有以下几种常用的值:

  • os.O_CREATE: create if none exists 不存在则创建
  • os.O_RDONLY: read-only 只读
  • os.O_WRONLY: write-only 只写
  • os.O_RDWR: read-write 可读可写
  • os.O_TRUNC: truncate when opened 文件长度截为0:即清空文件
  • os.O_APPEND: append 追加新数据到文件

对于文件权限参数,Linux系统中采用四位八进制数组成权限,比如0644 。对于每个新创建的文件或目录,系统都会自动赋予一个默认的权限。
可以使用umask命令设置文件或目录的默认权限。系统默认的权限掩码是0022

通常新建文件的默认权限值为0666,新建目录的默认权限为0777,需要与当前的权限掩码0022相减,可以得到06440755


读文件

func main()  {
	// 打开文件返回一个句柄
	file, _ := os.Open("D:\\Desktop\\readme.txt")
	defer file.Close()

	// 缓冲区
	buf := make([]byte, 1024)
	// 存放文件所有内容
	var bytes []byte

	for {
		// 每次读取一行放入缓冲区
		count, err := file.Read(buf)
		if err == io.EOF {
			break
		}
		bytes = append(bytes, buf[:count]...)
	}
	fmt.Println(string(bytes))
}

写文件

可以通过 Write()WriteString() 方法写入数据,最后通过 Sync() 方法将数据持久化到磁盘:

func main()  {
	file, _ := os.OpenFile("D:\\Desktop\\readme.txt", os.O_RDWR | os.O_APPEND | os.O_CREATE, 0644)
	defer file.Close()

	data := []byte("hello\nyes\nno\n")
	// 写入字节
	count, _ := file.Write(data)
	fmt.Println("第一次写入", count, "字节")
	// 写入字符串
	count, _ = file.WriteString("write string\n")
	fmt.Println("第二次写入", count, "字节")
	// 确保写入磁盘
	file.Sync()
}

更简单的ioutil


读文件

一次性读入所有内容:

func main()  {
	bytes, _ := ioutil.ReadFile("D:\\Desktop\\readme.txt")
	fmt.Println(string(bytes))
}

逐行读入:

func main()  {
	file, _ := os.Open("D:\\Desktop\\readme.txt")
	defer file.Close()
	// 接受io.Reader类型参数 返回一个bufio.Scanner实例
	scanner := bufio.NewScanner(file)

	var count int

	for scanner.Scan() {
		count++
		// 读取当前行内容
		line := scanner.Text()
		fmt.Println(count, ": " ,line)
	}
}

写文件

覆盖写入:

func main()  {
	data := []byte("hello\nyes\nno\n")
	ioutil.WriteFile("D:\\Desktop\\readme.txt", data, 0664)
}

追加:

func main()  {
	// 以指定的权限打开文件
	file, _ := os.OpenFile("D:\\Desktop\\readme.txt", os.O_RDWR | os.O_APPEND | os.O_CREATE, 0664)
	defer file.Close()
	data := []byte("greet\n")
	// 写入字节
	count, _ := file.Write(data)
	fmt.Println("第一次写入", count, "字节")
	// 写入字符串
	count, _ = file.WriteString("echo\n")
	fmt.Println("第二次写入", count, "字节")
	// 确保落盘
	file.Sync()
}

io.Writer和io.Reader接口


type Writer interface {
   Write(p []byte) (n int, err error)
}
type Writer interface {
   Write(p []byte) (n int, err error)
}

其实io 包就是围绕着实现了 io.Writer 和 io.Reader 接口类型的值而构建的。比如os.Fileio.Copyio.WriteStringio.PipeWriter/Readerioutil等等都实现了这两个接口,所以它们都可以读文件和写文件。当然我们也可以自行实现这两个接口。


io.LimitReader函数


在学习godis时,在aof.go文件中我看到一个关于io流的函数:io.LimitReader。该函数用于返回指定大小的Reader。

// LimitReader returns a Reader that reads from r
// but stops with EOF after n bytes.
// The underlying implementation is a *LimitedReader.
func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }

下面演示一下基本的使用:

func main()  {
	file, _ := os.Open("D:\\Desktop\\readme.txt")
	res := io.LimitReader(file, 20)
	data := make([]byte, 1024)
	count, err := res.Read(data)
	if err != nil {
		return
	}
	fmt.Println(string(data[:count]))
}

其中,res是一个Reader,且res只获取到了从文件开始往后20字节的内容。


 类似资料: