文件操作
io.Reader
所有实现
io.Reader的结构都实现了Read(p []byte) (n int, err error)
围绕io.Reader/Writer,有几个常用的实现:
net.Conn,os.Stdin,os.File: 网络、标准输入输出、文件的流读取strings.Reader: 把字符串抽象成Readerbytes.Reader: 把[]byte抽象成Readerbytes.Buffer: 把[]byte抽象成Reader和Writerbufio.Reader/Writer: 抽象成带缓冲的流读取(比如按行读写)
go
Conn,err := net.Dial()
sReader:= strings.NewReader()
bReader := bytes.NewReader()
bWriter := bytes.NewBuffer()
bufio.NewReader()/bufio.NewReader()读取文件
ioutil
go
//从一个io.Reader类型中读取内容直到返回错误或者EOF时返回读取的数据,当err == nil时,数据成功读取到[]byte中
//ReadAll函数被定义为从源中读取数据直到EOF,它是不会去从返回数据中去判断EOF来作为读取成功的依据
func ReadAll(r io.Reader) ([]byte, error)
//读取一个目录,并返回一个当前目录下的文件对象列表和错误信息
func ReadDir(dirname string) ([]os.FileInfo, error)
//读取文件内容,并返回[]byte数据和错误信息。err == nil时,读取成功
func ReadFile(filename string) ([]byte, error)bufio
go
//首先定义了一个用来缓冲io.Reader对象的结构体,同时该结构体拥有以下相关的方法
type Reader struct {
}
//NewReader函数用来返回一个默认大小buffer的Reader对象(默认大小好像是4096) 等同于NewReaderSize(rd,4096)
func NewReader(rd io.Reader) *Reader
//该函数返回一个指定大小buffer(size最小为16)的Reader对象,如果 io.Reader参数已经是一个足够大的Reader,它将返回该Reader
func NewReaderSize(rd io.Reader, size int) *Reader
//该方法返回从当前buffer中能被读到的字节数
func (b *Reader) Buffered() int
//Discard方法跳过后续的 n 个字节的数据,返回跳过的字节数。如果0 <= n <= b.Buffered(),该方法将不会从io.Reader中成功读取数据。
func (b *Reader) Discard(n int) (discarded int, err error)
//Peekf方法返回缓存的一个切片,该切片只包含缓存中的前n个字节的数据
func (b *Reader) Peek(n int) ([]byte, error)
//把Reader缓存对象中的数据读入到[]byte类型的p中,并返回读取的字节数。读取成功,err将返回空值
func (b *Reader) Read(p []byte) (n int, err error)
//返回单个字节,如果没有数据返回err
func (b *Reader) ReadByte() (byte, error)
//该方法在b中读取delimz之前的所有数据,返回的切片是已读出的数据的引用,切片中的数据在下一次的读取操作之前是有效的。如果未找到delim,将返回查找结果并返回nil空值。因为缓存的数据可能被下一次的读写操作修改,因此一般使用ReadBytes或者ReadString,他们返回的都是数据拷贝
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
//功能同ReadSlice,返回数据的拷贝
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
//功能同ReadBytes,返回字符串
func (b *Reader) ReadString(delim byte) (string, error)
//该方法是一个低水平的读取方式,一般建议使用ReadBytes('\n') 或 ReadString('\n'),或者使用一个 Scanner来代替。ReadLine 通过调用 ReadSlice 方法实现,返回的也是缓存的切片,用于读取一行数据,不包括行尾标记(\n 或 \r\n)
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
//读取单个UTF-8字符并返回一个rune和字节大小
func (b *Reader) ReadRune() (r rune, size int, err error)写入文件
func OpenFile(name string, flag int, perm FileMode) (*File, error)
name: 文件路径
flag: 打开的模式
下面的flag必须存在一个:
- O_RDONLY只读
- O_WRONLY只写
- O_RDWR读写
下面的flag是可选的:
- O_APPEND 追加模式(append)
- O_CREATE 文件不存在就创建(create a new file if none exists.)
- O_EXCL 与 O_CREATE 一起用,构成一个新建文件的功能,它要求文件必须不存在(used with O_CREATE, file must not exist)
- O_SYNC 同步方式打开,即不使用缓存,直接写入硬盘
- O_TRUNC 打开并清空文件
perm: Linux下的权限位
示例:
golang
func main() {
f, err := os.OpenFile("1.txt", os.O_RDWR|os.O_CREATE, 0644) //文件不存在则创建
if err != nil {
fmt.Println(err)
}
defer f.Close()
f.Write() //写入[]byte
f.WriteString() // 写入strings
}Bufio : 带有缓冲区的Writer
bufio 包自己封装了一个Writer,它的Writer是带有缓存的Writer,当写入的数据没有超过缓存大小时,他不会写入磁盘,当缓冲区写满后,它会一次将缓冲区中的内容写入磁盘,还有一种情况,当一次写入的大小已经大于缓冲区大小时,它会直接写入磁盘,也可以调用Flush()方法直接写入
go
func main() {
file, err := os.OpenFile("a.txt", os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
fmt.Println(err)
}
defer file.Close()
content := []byte("hello world!")
newWriter := bufio.NewWriter(file) // 也可以调用 NewWriterSize() 来设置缓冲区的大小
if _, err = newWriter.Write(content); err != nil {
fmt.Println(err)
}
fmt.Println("write file successful")
}