Common interface for GO io packages

  • 2020-05-09 18:43:41
  • OfStack

This paper analyzes the common interfaces of GO io packages with examples. Share with you for your reference. The specific analysis is as follows:

I have no C/C++ basis, no concept of interface, and came from Python. The minimalism of Python (one result often only provides one method) makes me very confused in Golang, especially in the read-write operation of files, because there are so many methods in Go's read-write operation of files, I don't know how to choose. It was not until I learned the concept of interface that I gradually understood package io and gradually fell in love with the flexibility of Golang. In my experience, interface is a very important knowledge point, which is the specification of 1 series of operations, especially the public interface, such as package io

This article lists only a few of the most commonly used interfaces. If you want to learn the io interface systematically, it is recommended to read the reference links at the bottom.

1. Overview of IO interface

package os provides a basic interface to the I/O primitive, making it a Shared public interface that abstracts generic functions and appends operations to a related primitive. Because these interfaces and primitives are wrappers around low-level operations that are completely different from the underlying implementation, the client should not assume that they are safe for concurrent execution unless otherwise notified.

The most important interfaces in package os are two: Reader and Writer. The various interfaces mentioned in this chapter are all related to these two interfaces, that is, once the two interfaces are implemented, it will have the functions of IO.

Tip:

var EOF = errors.New ("EOF"): defined in package io and used very frequently. Normally, EOF is returned when Read() cannot get any more returns, meaning that the file has reached the end (end-of-file).

2. io. Reader and io Writer

Definition:

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

Read reads len(p) bytes into p. When any error is encountered (including EOF), the number of bytes read will be returned immediately. When the function ends, the number of bytes successfully read and any errors will be returned.
Write writes len(p) byte data from p to the underlying data stream, then returns the number of bytes successfully written and any errors.

It's easy to guess from the interface name that, like 1, the interface naming convention in Go: the interface name ends with er. Note that this is not mandatory, and you can definitely not end with er. Some of the interfaces in the standard library don't end in er either.
Example:

func wr() {
 f, _ := os.Create("at.txt")
 defer f.Close()
 f.Write([]byte("Go is 1 A delightful programming language ")) // Write byte stream
 f.Seek(0, os.SEEK_SET)            // Reset the pointer  p := make([]byte, 2) // read 2 byte( len(buf)=2 )
 if _, err := f.Read(p); err != nil {
  log.Fatal("[F]", err)
 }
 fmt.Printf(" Read the characters \"%s\", Length of %d byte\n", p, len(p))  p = make([]byte, 50)
 if _, err := f.Read(p); err != nil {
  if err != io.EOF { // ignore EOF error
   log.Fatal("[F]", err)
  }
 }
 fmt.Printf(" Read the characters \"%s\", Length of %d byte\n", p, len(p))
}

Read the character "Go" with a length of 2 byte
Read characters "is a delightful programming language                        " with a length of 50 byte

3. io. ReaderAt and os WriterAt

Definition (off is short for offset) :

type ReaderAt interface {
    ReadAt(p []byte, off int64) (n int, err error)
} type WriterAt interface {
    WriteAt(p []byte, off int64) (n int, err error)
}

ReadAt() starts at the offset off of the base input source, and the rest is like Read() 1.
WriteAt() starts at the offset of the base input source, off, as well as Write() 1.

Example:

func at() {
 f, _ := os.Create("at.txt")
 defer f.Close()  f.WriteString("Go is 1 A delightful programming language ")
 f.WriteAt([]byte(" The program "), 26) // The offset 26byte Rewrite "programming" -> "Program"  fi, _ := f.Stat()              // Get file information
 p := make([]byte, fi.Size()-2) // File size minus offset
 f.ReadAt(p, 2)                 // The offset 2 byte  os.Stdout.Write(p)
}

4. io. ReaderFrom and os WriterTo

Definition:

type ReaderFrom interface {
    ReadFrom(r Reader) (n int64, err error)
} type WriterTo interface {
    WriteTo(w Writer) (n int64, err error)
}

ReadFrom() reads data from r until EOF or an error occurs. Returns the number of bytes read and other errors other than io.EOF. ReadFrom does not return EOF errors

WriteTo() writes data to w until there is no data to write or an error occurs. Returns the number of bytes written and any errors.

Example:

func fromTo() {
 r := strings.NewReader("Go is 1 A delightful programming language ") // create 1 a Reader
 w := bufio.NewWriter(os.Stdout)          // create 1 a Writer  w.ReadFrom(r) // w 1 Time sex read r In full
 w.Flush()  r.Seek(0, os.SEEK_SET) // Reset the pointer  r.WriteTo(w) // r 1 Secondary writes the content w In the
 w.Flush()
}

5. io.Seeker

Definition:

type Seeker interface {
    Seek(offset int64, whence int) (ret int64, err error)
}

Seek sets the offset (offset) for the next Read or Write, and its interpretation depends on whence. See above for an example.

The value of whence, and the corresponding constants are defined in the os package:

SEEK_SET int = 0 // Start at the beginning of the file  offset
SEEK_CUR int = 1 // The setting starts at the current location of the file's pointer offset
SEEK_END int = 2 // Start at the end of the file offset

6. io.Closer

Definition:

type Closer interface {
    Close() error
}

Used to shut down data streams and free up resources.

7. Other

type ByteReader interface {
 ReadByte() (c byte, err error)
} type RuneReader interface {
    ReadRune() (r rune, size int, err error)
}

ReadByte reads a single byte from the input and returns. If there are no bytes to read, an error is returned.
ReadRune reads a single utf-8 encoded character and returns that character and its byte length. If there are no valid characters, an error is returned.
func wr() {
 f, _ := os.Create("at.txt")
 defer f.Close()
 f.Write([]byte("Go is 1 A delightful programming language ")) // Write byte stream
 f.Seek(0, os.SEEK_SET)            // Reset the pointer  p := make([]byte, 2) // read 2 byte( len(buf)=2 )
 if _, err := f.Read(p); err != nil {
  log.Fatal("[F]", err)
 }
 fmt.Printf(" Read the characters \"%s\", Length of %d byte\n", p, len(p))  p = make([]byte, 50)
 if _, err := f.Read(p); err != nil {
  if err != io.EOF { // ignore EOF error
   log.Fatal("[F]", err)
  }
 }
 fmt.Printf(" Read the characters \"%s\", Length of %d byte\n", p, len(p))
}
0
WriteByte writes 1 byte and returns an error if the write fails.

Reference:
https://gowalker.org/io
https://github.com/polaris1119/The-Golang-Standard-Library-by-Example/blob/master/chapter01/01.1.md

I hope this article is helpful to you in the programming of GO language.


Related articles: