How to use the io.Reader interface
source link: https://yourbasic.org/golang/io-reader-interface-explained/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
How to use the io.Reader interface
Basics
The io.Reader
interface represents an entity
from which you can read a stream of bytes.
type Reader interface {
Read(buf []byte) (n int, err error)
}
Read
reads up to len(buf)
bytes into buf
and returns the number of bytes read –
it returns an io.EOF
error when the stream ends.
The standard library provides numerous Reader implementations (including in-memory byte buffers, files and network connections), and Readers are accepted as input by many utilities (including the HTTP client and server implementations).
Use a built-in reader
As an example, you can create a Reader from a string using the strings.Reader
function and then pass the Reader directly to the http.Post
function in package net/http
.
The Reader is then used as the source for the data to be posted.
r := strings.NewReader("my request")
resp, err := http.Post("http://foo.bar",
"application/x-www-form-urlencoded", r)
Since http.Post
uses a Reader instead of a []byte
it’s trivial to, for instance, use the contents of a file instead.
Read directly from a byte stream
You can use the Read
function directly (this is the least common use case).
r := strings.NewReader("abcde")
buf := make([]byte, 4)
for {
n, err := r.Read(buf)
fmt.Println(n, err, buf[:n])
if err == io.EOF {
break
}
}
4 <nil> [97 98 99 100]
1 <nil> [101]
0 EOF []
Use io.ReadFull
to read exactly
len(buf)
bytes into buf
:
r := strings.NewReader("abcde")
buf := make([]byte, 4)
if _, err := io.ReadFull(r, buf); err != nil {
log.Fatal(err)
}
fmt.Println(buf)
if _, err := io.ReadFull(r, buf); err != nil {
fmt.Println(err)
}
[97 98 99 100]
unexpected EOF
Use ioutil.ReadAll
to read everything:
r := strings.NewReader("abcde")
buf, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Println(buf)
[97 98 99 100 101]
Buffered reading and scanning
The bufio.Reader
and bufio.Scanner
types wrap a Reader creating another Reader that also implements the interface but provides buffering and some help for textual input.
In this example we use a bufio.Scanner
to count the number of words in a text.
const input = `Beware of bugs in the above code;
I have only proved it correct, not tried it.`
scanner := bufio.NewScanner(strings.NewReader(input))
scanner.Split(bufio.ScanWords) // Set up the split function.
count := 0
for scanner.Scan() {
count++
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
fmt.Println(count)
16
Share:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK