欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

GO语言的IO方法实例小结

程序员文章站 2022-08-29 09:30:50
type pipewriter 复制代码 代码如下: type pipewriter struct {     // contains...

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
}