GO语言的IO方法实例小结
type pipewriter
type pipewriter struct {
// contains filtered or unexported fields
}
(1)func (w *pipewriter) close() error关闭管道,关闭时正在进行的read操作将返回eof,若管道内仍有未读取的数据,后续仍可正常读取
import (
"fmt"
"io"
)
func main() {
r, w := io.pipe()
go w.write([]byte("hello word"))
data := make([]byte, 10)
n, err := r.read(data)
w.close()
if err == io.eof {
fmt.println("executing read return eof")
fmt.println("executing read reads number", n)
}
n, _ = r.read(data)
fmt.println(string(data)) //hello word
fmt.println("next read number", n) //next read number 0
}
(2)func (w *pipewriter) closewitherror(err error) error这个函数和read里边的closewitherror是大同小异的,关闭管道,关闭时正在进行的read操作将返回参数传入的异常,若管道内仍有未读取的数据,后续仍可正常读取
import (
"errors"
"fmt"
"io"
)
func main() {
r, w := io.pipe()
go w.write([]byte("hello widuu"))
newerr := errors.new("your daye 突然关闭了")
w.closewitherror(newerr)
data := make([]byte, 10)
_, err := r.read(data)
if err != nil {
fmt.println(err) //your daye 突然关闭了
}
}
(3)func (w *pipewriter) write(data []byte) (n int, err error)终于来打write了,这个是把字节切片写入管道,返回的是写入字节数和error,前边用到的太多了,随便哪一个吧
import (
"fmt"
"io"
)
func main() {
r, w := io.pipe()
go w.write([]byte("hello widuu")) //写入的是[]byte,注意官方文档写的是,写入管道阻塞,一直到所有数据的读取结束
data := make([]byte, 11)
n, _ := r.read(data)
fmt.println(string(data)) //hello widuu
fmt.println("read number", n) //read number 10
}
type reader
type reader interface {
read(p []byte) (n int, err error)
}
(1)func limitreader(r reader, n int64) reader,我们之前就说了reader这个结构,其实这就是对reader的一次封装,限定了它读取字节数,其实他实现的就是io.limitedreader{}这个结构
import (
"fmt"
"io"
"os"
"reflect"
)
func main() {
f, _ := os.open("test.txt")
defer f.close()
reader := io.limitreader(f, 5)
p := make([]byte, 5)
fmt.println(reflect.typeof(reader)) //*io.limitedreader
var total int
for {
n, err := reader.read(p)
if err == io.eof {
fmt.println("read value", string(p[:total])) //read value hello
fmt.println(total) //5
break
}
total = total + n
}
}
(2)func multireader(readers ...reader) reader这个函数一看就知道是封装了多个readers,跟上边的方法差不多,只是封装了多个而已,当然还去除了读取的限制,我们代码给大家测试一下
import (
"fmt"
"io"
"os"
"reflect"
)
func main() {
f1, _ := os.open("test1.txt")
f2, _ := os.open("test.txt")
defer f1.close()
defer f2.close()
reader := io.multireader(f1, f2) //*io.multireader
fmt.println(reflect.typeof(reader))
p := make([]byte, 10)
var total int
var data string
for {
n, err := reader.read(p)
if err == io.eof {
fmt.println("read end", total) //read end 17
break
}
total = total + n
data = data + string(p[:n])
}
fmt.println("read value", data) //read value widuu2hello widuu
fmt.println("read count", total) // read count 17
}
(3)既然上边介绍读了,我这介绍个写吧type write`func multiwriter(writers ...writer) writer一样的作用只不过是这次换成写了
import (
"fmt"
"io"
"io/ioutil"
"os"
)
func main() {
f1, _ := os.create("1.txt")
f2, _ := os.create("2.txt")
writer := io.multiwriter(f1, f2)
writer.write([]byte("widuu"))
//千万别这么逻辑来 ,我这是测试用的哈
r1, _ := ioutil.readfile("1.txt")
r2, _ := ioutil.readfile("2.txt")
fmt.println(string(r1)) //widuu
fmt.println(string(r2)) //widuu
}
(4)func teereader(r reader, w writer) reader这个方法有意思是从r中读取数据然后写入到w中,这个没有内部缓冲区,看下代码
import (
"fmt"
"io"
"os"
"reflect"
)
func main() {
r, _ := os.open("test.txt")
w, _ := os.create("test2.txt")
reader := io.teereader(r, w)
fmt.println(reflect.typeof(reader)) //*io.teereader
p := make([]byte, 10)
n, _ := reader.read(p)
fmt.println(string(p[:n])) //hello widu
}
type sectionreader{}
type sectionreader struct {
// contains filtered or unexported fields
}
(1)func newsectionreader(r readerat, off int64, n int64) *sectionreader,你一看就知道了,其实就是通过这个方法获取到io.sectionreader,第一个参数读取器,第二个参数偏移量,第三个参数是读取多少
import (
"fmt"
"io"
"os"
"reflect"
)
func main() {
f, _ := os.open("test.txt")
sr := io.newsectionreader(f, 2, 5)
fmt.println(reflect.typeof(sr)) //*io.sectionreader
}
(2)func (s *sectionreader) read(p []byte) (n int, err error)熟悉的read()其实就是读取数据用的,大家看函数就可以理解了,因为咱们经常遇到这个上两个都写这个了~~
import (
"fmt"
"io"
"os"
)
func main() {
f, _ := os.open("test.txt")
defer f.close()
sr := io.newsectionreader(f, 2, 5)
p := make([]byte, 10)
n, err := sr.read(p)
if err != nil {
fmt.println(err)
}
fmt.println(string(p[:n])) //llo w
}
(3)func (s *sectionreader) readat(p []byte, off int64) (n int, err error)额这个跟之前的readat是一样的,只不过只有一个偏移量,少了截取数,但是你要知道sectionreader做的是什么就把数据截取了,所以就不需要截取数了
import (
"fmt"
"io"
"os"
)
func main() {
f, _ := os.open("test.txt")
defer f.close()
sr := io.newsectionreader(f, 2, 5)
p := make([]byte, 10)
n, err := sr.readat(p, 1)
if err == io.eof {
fmt.println(string(p[:n])) // lo w
}
}
(4)func (s *sectionreader) seek(offset int64, whence int) (int64, error)这个是设置文件指针的便宜量的,之前我们的os里边也是有个seek的,对sectionreader的读取起始点、当前读取点、结束点进行偏移,offset 偏移量,whence 设定选项 0:读取起始点,1:当前读取点,2:结束点(不好用),其他:将抛出seek: invalid whence异常
import (
"fmt"
"io"
"os"
)
func main() {
f, _ := os.open("test.txt")
defer f.close()
sr := io.newsectionreader(f, 2, 5)
p := make([]byte, 10)
sr.seek(1, 0) //相当于起始的地址偏移1
n, err := sr.read(p)
if err != nil {
fmt.println(err)
}
fmt.println(string(p[:n])) //lo w 是不是达到了前边的readat()
}
(5)func (s *sectionreader) size() int64返回的是可以读取的字节数,这个不受偏移指针的影响,也不受当前读取的影响,我们具体看下代码
import (
"fmt"
"io"
"os"
)
func main() {
f, _ := os.open("test.txt")
defer f.close()
sr := io.newsectionreader(f, 2, 5)
fmt.println(sr.size()) //5
p := make([]byte, 10)
sr.seek(1, 0) //相当于起始的地址偏移1
n, err := sr.read(p)
if err != nil {
fmt.println(err)
}
fmt.println(string(p[:n])) //lo w
fmt.println(sr.size()) //5
}
上一篇: Go语言编程中对文件读写的基本方法整理
下一篇: 举例详解Go语言中os库的常用函数用法