Our first Reader
To understand Readers and Writers I will go through the implementations of these interfaces and see how they are used.
When coding you mostly use already defined implementations, so it's useful to go through most of them and see how they are used.
That being said, let's check out the first concrete implementation of io.Reader: the strings.Reader.
strings.Reader
The simplest reader is a strings.Reader.
Keep in mind that strings.Reader
is not the same as io.Reader
. io.Reader
is an interface and strings.Reader
is one of
the many
concrete implementations of that interface.
The bellow example is taken from the Go Tour:
It creates a new Reader with:
r := strings.NewReader("Hello, Reader!")
and then consumes its output 8 bytes at a time:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Hello, Reader!")
b := make([]byte, 8)
for {
n, err := r.Read(b)
fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
fmt.Printf("b[:n] = %q\n", b[:n])
if err == io.EOF {
break
}
}
}
Output:
n = 8 err = <nil> b = [72 101 108 108 111 44 32 82]
b[:n] = "Hello, R"
n = 6 err = <nil> b = [101 97 100 101 114 33 32 82]
b[:n] = "eader!"
n = 0 err = EOF b = [101 97 100 101 114 33 32 82]
b[:n] = ""
io.ReadFull
Above, we used directly the .Read()
method to read data from our reader. You won't use this method that often.
io.ReadFull is used when you want to read an exact number of bytes from our reader .
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
r := strings.NewReader("Hello, Reader!")
buf := make([]byte, 5)
if _, err := io.ReadFull(r, buf); err != nil {
log.Fatal(err)
}
fmt.Println(buf)
fmt.Println(string(buf))
}
[72 101 108 108 111]
Hello
io.ReadAll
The io.ReadAll function reads all bytes from your Reader:
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
r := strings.NewReader("Hello, Reader!")
data, err := io.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Println(data)
fmt.Println(string(data))
}
[72 101 108 108 111 44 32 82 101 97 100 101 114 33]
Hello, Reader!
Conclusion
So far you've learned about the strings.Reader
and also how to read an exact number of bytes with io.ReadFull
or how to read all bytes from it with io.ReadAll
.
Keep in mind strings.Reader
is just one of the many implementations of io.Reader. You can use io.ReadFull
and io.ReadAll
functions on all io.Reader
implementations.