Go语言学习之bufio包(The way to go)
2017-04-15 00:34
771 查看
生命不止,继续Go go go.
还记得吗,我们之前介绍过ioutil包,今天继续再介绍一下bufio包吧。
从字面就看出来了,有buf,那就是缓冲的意思。
Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer object, creating another object (Reader or Writer) that also implements the interface but provides buffering and some help for textual I/O.
bufio 包实现了缓存IO。它包装了 io.Reader 和 io.Writer 对象,创建了另外的Reader和Writer对象,它们也实现了io.Reader和io.Writer接口,不过它们是有缓存的。该包同时为文本I/O提供了一些便利操作。
NewReaderSize
作用:
NewReaderSize 将 rd 封装成一个带缓存的 bufio.Reader 对象,
缓存大小由 size 指定(如果小于 16 则会被设置为 16)。
如果 rd 的基类型就是有足够缓存的 bufio.Reader 类型,则直接将
rd 转换为基类型返回。
NewReader
NewReader 相当于 NewReaderSize(rd, 4096)
Peek
Peek 返回缓存的一个切片,该切片引用缓存中前 n 个字节的数据,
该操作不会将数据读出,只是引用,引用的数据在下一次读取操作之
前是有效的。如果切片长度小于 n,则返回一个错误信息说明原因。
如果 n 大于缓存的总大小,则返回 ErrBufferFull。
应用
新建一个file文件,输入wangshubo1989
输出:wangs
Read
Read 从 b 中读出数据到 p 中,返回读出的字节数和遇到的错误。
如果缓存不为空,则只能读出缓存中的数据,不会从底层 io.Reader
中提取数据,如果缓存为空,则:
1、len(p) >= 缓存大小,则跳过缓存,直接从底层 io.Reader 中读出到 p 中。
2、len(p) < 缓存大小,则先将数据从底层 io.Reader 中读取到缓存
中,再从缓存读取到 p 中。
Buffered
Buffered 返回缓存中未读取的数据的长度。
Discard
Discard 跳过后续的 n 个字节的数据,返回跳过的字节数。
如果结果小于 n,将返回错误信息。
如果 n 小于缓存中的数据长度,则不会从底层提取数据。
NewWriterSize
NewWriterSize 将 wr 封装成一个带缓存的 bufio.Writer 对象,
缓存大小由 size 指定(如果小于 4096 则会被设置为 4096)。
如果 wr 的基类型就是有足够缓存的 bufio.Writer 类型,则直接将
wr 转换为基类型返回。
NewWriter
NewWriter 相当于 NewWriterSize(wr, 4096)
WriteString
WriteString 功能同 Write,只不过写入的是字符串
WriteRune
WriteRune 向 b 写入 r 的 UTF-8 编码,返回 r 的编码长度。
Flush
Flush 将缓存中的数据提交到底层的 io.Writer 中
Available
Available 返回缓存中未使用的空间的长度
Buffered
Buffered 返回缓存中未提交的数据的长度
Reset
Reset 将 b 的底层 Writer 重新指定为 w,同时丢弃缓存中的所有数据,复位
所有标记和错误信息。相当于创建了一个新的 bufio.Writer。
应用
在 bufio 包中有多种方式获取文本输入,ReadBytes、ReadString 和独特的 ReadLine,对于简单的目的这些都有些过于复杂了。在 Go 1.1 中,添加了一个新类型,Scanner,以便更容易的处理如按行读取输入序列或空格分隔的词等,这类简单的任务。它终结了如输入一个很长的有问题的行这样的输入错误,并且提供了简单的默认行为:基于行的输入,每行都剔除分隔标识。
应用
运行结果:
wangshubo1989
WANGSHUBO1989
还记得吗,我们之前介绍过ioutil包,今天继续再介绍一下bufio包吧。
从字面就看出来了,有buf,那就是缓冲的意思。
Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer object, creating another object (Reader or Writer) that also implements the interface but provides buffering and some help for textual I/O.
bufio 包实现了缓存IO。它包装了 io.Reader 和 io.Writer 对象,创建了另外的Reader和Writer对象,它们也实现了io.Reader和io.Writer接口,不过它们是有缓存的。该包同时为文本I/O提供了一些便利操作。
Reader 类型和方法
Reader结构type Reader struct { buf []byte // 缓存 rd io.Reader // 底层的io.Reader r, w int err error // 读过程中遇到的错误 lastByte int // 最后一次读到的字节 lastRuneSize int // 最后一次读到的Rune的大小 }
NewReaderSize
func NewReaderSize(rd io.Reader, size int) *Reader
作用:
NewReaderSize 将 rd 封装成一个带缓存的 bufio.Reader 对象,
缓存大小由 size 指定(如果小于 16 则会被设置为 16)。
如果 rd 的基类型就是有足够缓存的 bufio.Reader 类型,则直接将
rd 转换为基类型返回。
NewReader
func NewReader(rd io.Reader) *Reader
NewReader 相当于 NewReaderSize(rd, 4096)
Peek
func (b *Reader) Peek(n int) ([]byte, error)
Peek 返回缓存的一个切片,该切片引用缓存中前 n 个字节的数据,
该操作不会将数据读出,只是引用,引用的数据在下一次读取操作之
前是有效的。如果切片长度小于 n,则返回一个错误信息说明原因。
如果 n 大于缓存的总大小,则返回 ErrBufferFull。
应用
新建一个file文件,输入wangshubo1989
package main import ( "bufio" "fmt" "os" ) func main() { f, _ := os.Open("file") r4 := bufio.NewReader(f) b4, _ := r4.Peek(5) fmt.Printf("5 bytes: %s\n", string(b4)) f.Close() }
输出:wangs
Read
func (b *Reader) Read(p []byte) (n int, err error)
Read 从 b 中读出数据到 p 中,返回读出的字节数和遇到的错误。
如果缓存不为空,则只能读出缓存中的数据,不会从底层 io.Reader
中提取数据,如果缓存为空,则:
1、len(p) >= 缓存大小,则跳过缓存,直接从底层 io.Reader 中读出到 p 中。
2、len(p) < 缓存大小,则先将数据从底层 io.Reader 中读取到缓存
中,再从缓存读取到 p 中。
Buffered
func (b *Reader) Buffered() int
Buffered 返回缓存中未读取的数据的长度。
Discard
func (b *Reader) Discard(n int) (discarded int, err error)
Discard 跳过后续的 n 个字节的数据,返回跳过的字节数。
如果结果小于 n,将返回错误信息。
如果 n 小于缓存中的数据长度,则不会从底层提取数据。
Writer 类型和方法
writer结构type Writer struct { err error // 写过程中遇到的错误 buf []byte // 缓存 n int // 当前缓存中的字节数 wr io.Writer // 底层的 io.Writer 对象 }
NewWriterSize
func NewWriterSize(wr io.Writer, size int) *Writer
NewWriterSize 将 wr 封装成一个带缓存的 bufio.Writer 对象,
缓存大小由 size 指定(如果小于 4096 则会被设置为 4096)。
如果 wr 的基类型就是有足够缓存的 bufio.Writer 类型,则直接将
wr 转换为基类型返回。
NewWriter
func NewWriter(wr io.Writer) *Writer
NewWriter 相当于 NewWriterSize(wr, 4096)
WriteString
func (b *Writer) WriteString(s string) (int, error)
WriteString 功能同 Write,只不过写入的是字符串
WriteRune
func (b *Writer) WriteRune(r rune) (size int, err error)
WriteRune 向 b 写入 r 的 UTF-8 编码,返回 r 的编码长度。
Flush
func (b *Writer) Flush() error
Flush 将缓存中的数据提交到底层的 io.Writer 中
Available
func (b *Writer) Available() int
Available 返回缓存中未使用的空间的长度
Buffered
func (b *Writer) Buffered() int
Buffered 返回缓存中未提交的数据的长度
Reset
func (b *Writer) Reset(w io.Writer)
Reset 将 b 的底层 Writer 重新指定为 w,同时丢弃缓存中的所有数据,复位
所有标记和错误信息。相当于创建了一个新的 bufio.Writer。
应用
// Writing files in Go follows similar patterns to the // ones we saw earlier for reading. package main import ( "bufio" "fmt" "io/ioutil" "os" ) func check(e error) { if e != nil { panic(e) } } func main() { // To start, here's how to dump a string (or just // bytes) into a file. d1 := []byte("hello\ngo\n") err := ioutil.WriteFile("/tmp/dat1", d1, 0644) check(err) // For more granular writes, open a file for writing. f, err := os.Create("/tmp/dat2") check(err) // It's idiomatic to defer a `Close` immediately // after opening a file. defer f.Close() // You can `Write` byte slices as you'd expect. d2 := []byte{115, 111, 109, 101, 10} n2, err := f.Write(d2) check(err) fmt.Printf("wrote %d bytes\n", n2) // A `WriteString` is also available. n3, err := f.WriteString("writes\n") fmt.Printf("wrote %d bytes\n", n3) // Issue a `Sync` to flush writes to stable storage. f.Sync() // `bufio` provides buffered writers in addition // to the buffered readers we saw earlier. w := bufio.NewWriter(f) n4, err := w.WriteString("buffered\n") fmt.Printf("wrote %d bytes\n", n4) // Use `Flush` to ensure all buffered operations have // been applied to the underlying writer. w.Flush() }
Scanner 类型和方法
这个应该算是go中的特色了吧,反正对于c++过来的人说挺特别的。在 bufio 包中有多种方式获取文本输入,ReadBytes、ReadString 和独特的 ReadLine,对于简单的目的这些都有些过于复杂了。在 Go 1.1 中,添加了一个新类型,Scanner,以便更容易的处理如按行读取输入序列或空格分隔的词等,这类简单的任务。它终结了如输入一个很长的有问题的行这样的输入错误,并且提供了简单的默认行为:基于行的输入,每行都剔除分隔标识。
应用
// A _line filter_ is a common type of program that reads // input on stdin, processes it, and then prints some // derived result to stdout. `grep` and `sed` are common // line filters. // Here's an example line filter in Go that writes a // capitalized version of all input text. You can use this // pattern to write your own Go line filters. package main import ( "bufio" "fmt" "os" "strings" ) func main() { // Wrapping the unbuffered `os.Stdin` with a buffered // scanner gives us a convenient `Scan` method that // advances the scanner to the next token; which is // the next line in the default scanner. scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { // `Text` returns the current token, here the next line, // from the input. ucl := strings.ToUpper(scanner.Text()) // Write out the uppercased line. fmt.Println(ucl) } // Check for errors during `Scan`. End of file is // expected and not reported by `Scan` as an error. if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "error:", err) os.Exit(1) } }
运行结果:
wangshubo1989
WANGSHUBO1989
相关文章推荐
- Go语言学习之flag包(The way to go)
- Go语言学习之archive/zip、compress/zlib、compress/gzip包(the way to go)
- Go语言学习之运算符(The way to go)
- Go语言学习之encoding/json包(The way to go)
- Go语言学习之map (The way to go)
- Go语言学习之errors包(The way to go)
- Go语言学习之struct(The way to go)
- Go语言学习之指针(The way to go)
- Go语言学习之函数(The way to go)
- Go语言学习之net包(The way to go)
- Go语言学习之time包(获取当前时间戳等)(the way to go)
- Go语言学习之encoding/gob包(The way to go)
- Go语言学习之变量(The way to go)
- Go语言学习之ioutil包(The way to go)
- Go语言学习之runtime包(The way to go)
- Go语言学习之Hello World(The way to go)
- Go语言学习之常量(The way to go)
- Go语言学习之image、image/color、image/png、image/jpeg包(the way to go)
- Go语言学习之method(The way to go)
- Go语言学习之Arrays和Slices (The way to go)