This is a creation in Article, where the information may have evolved or changed.
Go
pkg
There are some cores in the native interface
, which io.Reader/Writer
are the more commonly used interfaces. Many native constructs revolve around this series of interfaces, and during the actual development process, you will find that through this interface you can transition and transform between many different IO types. This paper summarizes the actual situation.
General overview
Around io.Reader/Writer
, there are several common implementations:
- Net. Conn, OS. Stdin, OS. File: Stream read for network, standard input and output, files
- Strings. Reader: abstract strings into reader
- bytes. Reader:
[]byte
abstract into reader
- bytes. Buffer:
[]byte
abstract into reader and writer
- Bufio. Reader/writer: Abstraction into buffered stream reads (e.g. read-write by line)
These implementations for beginners are actually more difficult to remember, in the face of practical problems is a mask, I do not know how to be good. Here's an example of the actual scenario.
Examples of scenarios
0. base64 encoded into a string
encoding/base64
Subpackages
func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser
This is used for base64
coding, but careful observation reveals that it requires an IO. Writer is the output target and writes the result to the target using the returned WriteCloser
write method, here is an example of the GO official document
input := []byte("foo\x00bar")encoder := base64.NewEncoder(base64.StdEncoding, os.Stdout)encoder.Write(input)
This example writes the result to Stdout
, what if we want to get a string? Observe the above diagram, or you can use bytes. Buffer as the target io.Writer
:
input := []byte("foo\x00bar")buffer := new(bytes.Buffer)encoder := base64.NewEncoder(base64.StdEncoding, buffer)encoder.Write(input)fmt.Println(string(buffer.Bytes())
1. [Positive and negative serialization between]byte and struct
This scenario is often used on byte-based protocols, such as having a fixed-length structure:
type Protocol struct { Version uint8 BodyLen uint16 Reserved [2]byte Unit uint8 Value uint32}
By one []byte
to deserialize this Protocol
, one idea is to traverse this []byte
, and then assign values. In fact, encoding/binary
there is a convenient way in the package:
func Read(r io.Reader, order ByteOrder, data interface{}) error
This method io.Reader
reads bytes from one and has order
the specified end pattern, to give the padding data
(data needs to be fixed-sized structure or type). To use this method io.Reader
, first of all, from the above diagram is not difficult to find, we can write:
var p Protocolvar bin []byte//...binary.Read(bytes.NewReader(bin), binary.LittleEndian, &p)
In other words, we []byte
turn one into one io.Reader
.
In turn, we need to Protocol
serialize it []byte
, using a encoding/binary
corresponding method in the package Write
:
func Write(w io.Writer, order ByteOrder, data interface{}) error
By []byte
turning it into one io.Writer
:
var p Protocolbuffer := new(bytes.Buffer)//...binary.Writer(buffer, binary.LittleEndian, p)bin := buffer.Bytes()
2. Read by rows from the stream
For example, for a common text-line-based HTTP
protocol, we need to read a stream in line. Essentially, we need a buffer-based read-write mechanism (read some buffers and then iterate over the bytes or characters we care about in the buffer). There is a package in go that bufio
can read and write with buffering:
func NewReader(rd io.Reader) *Readerfunc (b *Reader) ReadString(delim byte) (string, error)
This readstring method io.Reader
reads the string from within, until delim
it returns delim
and precedes the string. If delim
it is set to \n
, it is equivalent to reading by line:
var conn net.Conn//...reader := NewReader(conn)for { line, err := reader.ReadString([]byte('\n')) //...}
Fancy Technology (Zuo) Qiao (SI)
string Turn []byte
a := "Hello, playground"fmt.Println([]byte(a))
Equivalent to
A: = "Hello, playground" BUF: = new (bytes. Buffer) buf. Readfrom (Strings. Newreader (a)) fmt. Println (BUF. Bytes ())