golang标准库io包 input output
io操作是一个很庞大的工程,被封装到了许多包中以供使用
先来讲最基本的io接口
Go语言中最基本的I/O接口是io.Reader
和io.Writer
。这些接口定义了读取和写入数据的通用方法,为不同类型的数据源和数据目标提供了统一的接口。
-
Reader 接口:
Read(p []byte) (n int, err error)
方法定义了读取数据的通用方式。p
参数是一个字节切片,用于接收从数据源中读取的数据。n
返回值表示读取的字节数,通常是成功读取的字节数。err
返回值是一个可能的错误,如果读取过程中出现问题,就会返回错误信息。
Reader
接口的实现可以用于从不同类型的数据源(如文件、网络连接、内存缓冲区等)读取数据,并将数据存储到提供的字节切片中。 -
Writer 接口:
Write(p []byte) (n int, err error)
方法定义了写入数据的通用方式。p
参数是一个字节切片,包含要写入的数据。n
返回值表示写入的字节数,通常是成功写入的字节数。err
返回值是一个可能的错误,如果写入过程中出现问题,就会返回错误信息。
Writer
接口的实现可以用于将数据写入不同类型的数据目标(如文件、网络连接、内存缓冲区等)。
Reader接口
type Reader interface {Read(P []byte) (n int, err error)
}
Writer接口
type Writer interface {Write(P []byte) (n int, err error)
}
可以看到:这两个基础的接口实现次数非常多
读字符串:
r := strings.NewReader("hello world")
buf := make([]byte, 20)
r.Read(buf)
fmt.Println("string(buf):", string(buf))
r := strings.NewReader("hello world")
:这一行创建了一个名为r
的字符串读取器(*strings.Reader
),并将其初始化为包含字符串 “hello world” 的读取器。buf := make([]byte, 20)
:这一行创建了一个名为buf
的字节切片(byte slice),切片的长度为 20 个字节。r.Read(buf)
:这一行通过字符串读取器r
从其内容中读取数据,然后将读取的数据存储到字节切片buf
中。在这里,它会尝试从字符串 “hello world” 中读取数据并将其存储在buf
中。由于buf
的长度为 20,因此最多会读取 20 个字节。如果 “hello world” 的长度不足 20 个字节,那么只会读取实际长度的字节。fmt.Println("string(buf):", string(buf))
:最后,这一行将buf
中的字节数据转换为字符串,并打印出来。这将输出 “string(buf): hello world”,因为 “hello world” 是读取的字符串数据。
golang标准库bufio
bufio
(缩写自"buffered I/O")是Go语言标准库中的一个包,用于提供缓冲读写功能,以提高I/O操作的效率。bufio
包中包含了一些类型和函数,可以帮助你在读写数据时减少系统调用的次数,从而提高性能。
类型:
bufio.Reader
:用于包装io.Reader
接口,提供缓冲读取功能。通过使用Reader
,你可以一次读取大块数据,并以更小的块进行处理,减少I/O操作的次数。bufio.Writer
:用于包装io.Writer
接口,提供缓冲写入功能。通过使用Writer
,你可以将数据一次写入缓冲区,然后在需要时刷新到底层io.Writer
,从而减少写入操作的次数。bufio.Scanner
:用于逐行扫描文本,可以通过自定义的分隔符分割文本。这对于处理文本文件特别有用。
函数:
-
bufio.NewReader
:用于创建一个新的bufio.Reader
,以包装一个io.Reader
。这个函数会返回一个具有默认缓冲大小的Reader
。 -
bufio.NewWriter
:用于创建一个新的bufio.Writer
,以包装一个io.Writer
。这个函数会返回一个具有默认缓冲大小的Writer
。 -
bufio.NewScanner
:用于创建一个新的bufio.Scanner
,以包装一个io.Reader
。这个函数会返回一个Scanner
,它可以逐行扫描文本。 -
bufio.NewScanner
:用于创建一个新的bufio.Scanner
,以包装一个io.Reader
。这个函数会返回一个Scanner
,它可以逐行扫描文本。 -
Scanner.Split
:用于自定义分隔符的Scanner
,默认情况下使用换行符分割文本。 -
Reader.Read
:用于从缓冲区中读取数据,当缓冲区为空时,它会从底层io.Reader
中读取更多数据并填充缓冲区。 -
Writer.Write
:用于将数据写入缓冲区,当缓冲区满时,它会将数据刷新到底层的io.Writer
。 -
Writer.Flush
:用于手动刷新bufio.Writer
的缓冲区,确保缓冲中的数据被写入底层io.Writer
。
- 缓冲大小:默认情况下,
bufio.Reader
和bufio.Writer
使用4096字节的缓冲区。你可以使用自定义的缓冲大小来优化性能,根据你的应用程序需求。 - 性能提升:通过减少I/O操作的次数,
bufio
可以显著提高文件和网络读写的性能。特别是对于大型数据集或高并发的情况,bufio
非常有用。
//r := strings.NewReader("hello world")
f, _ := os.Open("a.txt")
defer f.Close()
r2 := bufio.NewReader(f)
s, _ := r2.ReadString('\n')
fmt.Println(s)
可以把读取的串或文件内的值直接封装到s中
读取Readstring,ReadSlice,ReadLine,ReadBytes等等,都是一样的道理
func test6() {s := strings.NewReader("ABC DEF GHI JKL")br := bufio.NewReader(s)w, _ := br.ReadBytes(' ')fmt.Println(string(w))w, _ = br.ReadBytes(' ')fmt.Println(string(w))w, _ = br.ReadBytes(' ')fmt.Println(string(w))w, _ = br.ReadBytes(' ')fmt.Println(string(w))
}
写:
func test9() {f, _ := os.OpenFile("a.txt", os.O_CREATE|os.O_RDWR, os.ModePerm)defer f.Close()//bufio.NewWriter(f)w := bufio.NewWriter(f)w.WriteString("hello world")w.Flush()
}
可以把hello world写进a.txt中。
Reset可以清空缓冲区。
Scan相关函数:扫描:ScanBytes ScanRunes ScanWords ScanLines …
func test10() {s := strings.NewReader("ABC DEF GHI JKL")bs := bufio.NewScanner(s)bs.Split(bufio.ScanWords)for bs.Scan() {fmt.Println(bs.Text())}
}
bufio.ScanWords可以将字符串按照空格分隔