The basic method of reading and writing files in Go language programming


func Copy(dst Writer, src Reader) (written int64, err error) (written int64, err error) this function reads and copies from one file to another, and 1 directly copies to EOF which reads the file, so it does not return io.EOF error

import (
 "fmt"
 "io"
 "os"
)
func main() {
 r, _ := os.Open("test.txt")
 w, _ := os.Create("write.txt")
 num, err := io.Copy(w, w)
 if err != nil {
  fmt.Println(err)
 }
 fmt.Println(num) // return int64 the 11  Open my write.txt It is test.txt The inside of the hello widuu

2.func CopyN(dst Writer, src Reader, n int64) (written int64, err error

import (
 "fmt"
 "io"
 "io/ioutil"
 "os"
)
func main() {
 r, _ := os.Open("test.txt")
 w, _ := os.Create("write1.txt")
 num, err := io.CopyN(w, r, 5)
 if err != nil {
  fmt.Println(err)
 }
 defer r.Close()
 b, _ := ioutil.ReadFile("write1.txt")
 fmt.Println(string(b)) // The output  hello
 fmt.Println(num)       //5
}

3.func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) (n int, err error) But if the number of bytes you read is 5, you’re going to return 1 ‘io.ErrUnexpectedEOF’, and if it’s greater than, you’re going to return ‘io.ErrShortBuffer’, and when you’re done, you’re going to have ‘io.EOF’ ~~, we’ll talk more about that, this Reader as long as we satisfy this interface

type Reader interface {
    Read(p []byte) (n int, err error)
}

Where *File supports func (f *File) Read(b []byte) (n int, err error)

import (
 "fmt"
 "io"
 "os"
)
func main() {
 r, _ := os.Open("write1.txt")
 b := make([]byte, 20)
 defer r.Close()
 var total int
 for {
  n, err := io.ReadAtLeast(r, b, 8)
  if err == nil {
   fmt.Println("Read enough value:", string(b)) // Read enough value: hello widuu
  }
  if err == io.ErrUnexpectedEOF { // The data read is less than the minimum read that we set 8
   fmt.Println("Read fewer value:", string(b[0:n]))
  }
  
  if err == io.ErrShortBuffer{   // This is what we set up buf That is b Less than we limit 8
   fmt.Println("buf too Short")
   os.Exit(1)
  }
  if err == io.EOF { // After reading the   The output
   fmt.Println("Read end total", total) //Read end total 11
   break
  }
  total = total + n
 }
}

func ReadFull(r Reader, buf []byte) (n int, err error) this function is similar to the one above, except that it reads len(buf) and puts them in buf

import (
 "fmt"
 "io"
 "os"
)
func main() {
 r, _ := os.Open("write.txt")
 b := make([]byte, 20)
 num, err := io.ReadFull(r, b)
 defer r.Close()
 if err == io.EOF {
  fmt.Println("Read end total", num)
 }
 if err == io.ErrUnexpectedEOF {
  fmt.Println("Read fewer value:", string(b[:num])) //Read fewer value: hello widuu , is still a buf The length is greater than the read length
  return
 }
 fmt.Println("Read  value:", string(b)) // if b is 5  That's right there
}

func WriteString(w Writer, s string) It’s all writer and this structure can be written

type Writer interface {
    Write(p []byte) (n int, err error)
}
 with read1 The sample of our *File There is a func (f *File) Write(b []byte) (n int, err error) Of course we do *File It's already there WirteString the func (f *File) WriteString(s string) (ret int, err error)
import (
 "fmt"
 "io"
 "io/ioutil"
 "os"
)
func main() {
 w, _ := os.OpenFile("write1.txt", os.O_RDWR, os.ModePerm)
 n, err := io.WriteString(w, "ni hao ma")
 if err != nil {
  fmt.Println(err) // When I use os.open() I don't have permission    The miserable ~~ The output write write1.txt: Access is denied.
 }
 defer w.Close()
 b, _ := ioutil.ReadFile("write1.txt")
 fmt.Println("write total", n) //write total 9
 fmt.Println(string(b))        // ni hao ma
}

6.type LimitedReader

type LimitedReader struct {
    R Reader //  The reader
    N int64  //  Maximum byte limit
}

Only one method was implemented, func (l *LimitedReader), Read(p []byte) (n int, err error)

import (
 "fmt"
 "io"
 "os"
)
func main() {
 reader, _ := os.Open("test.txt")
 limitedreader := io.LimitedReader{
  R: reader,
  N: 20,
 }
 p := make([]byte, 10)
 var total int
 for {
  n, err := limitedreader.Read(p)
  if err == io.EOF {
   fmt.Println("read total", total)     //read total 11
   fmt.Println("read value", string(p)) //read value hello widuu
   break
  }
  total = total + n
 }
}

7.type PipeReader

type PipeReader struct {
    // contains filtered or unexported fields
}

(1)func Pipe() (*PipeReader, *PipeWriter) creates a pipe and returns its reader and writer. This will synchronize the pipe in memory. Its opening will io.Reader and then wait for the input of io.Writer

import (
 "fmt"
 "io"
 "reflect"
)
func main() {
 r, w := io.Pipe()
 fmt.Println(reflect.TypeOf(r)) //*io.PipeReader
 fmt.Println(reflect.TypeOf(w)) //*io.PipeWriter
}

(2)func (r *PipeReader) Close() error (Write) ErrClosedPipe is returned after an ongoing or subsequent write to Write operation has been closed

import (
 "fmt"
 "io"
)
func main() {
 r, w := io.Pipe()
 r.Close()
 _, err := w.Write([]byte("hello widuu")) 
 if err == io.ErrClosedPipe {
  fmt.Println(" The pipe is closed and cannot write ") // The pipe is closed and cannot write
 }
}

(3)func (r *PipeReader) CloseWithError(err error) error this is r up here.Close when closed, the writer will return an error message

import (
 "errors"
 "fmt"
 "io"
)
func main() {
 r, w := io.Pipe()
 r.Close()
 err := errors.New(" The pipe break is closed ") //errors We've talked about this bag before, just 1 A method of New No, you can look ahead
 r.CloseWithError(err)
 _, err = w.Write([]byte("test"))
 if err != nil {
  fmt.Println(err) // The pipe break is closed
 }
}

(4)func (r *PipeReader) Read(data []byte) (n int, err error) (n int, err byte) (n int, err error

import (
 "fmt"
 "io"
)
func main() {
 r, w := io.Pipe()
 go w.Write([]byte("hello widuu"))
 d := make([]byte, 11)
 n, _ := r.Read(d) // Reading data from a pipe
 fmt.Println(string(d))
 fmt.Println(n)
}