Golang reader
Tags: go
Published: 2020-05-12 14:16:39

The IO package provides the basic interface to the original I/O language. It mainly wraps up the existing implementations of these original languages.

Since these interface-wrapped I/O originals are implemented by different low-level operations, their parallel execution should not be assumed to be safe until stated otherwise.

One of the most important interfaces in an IO package is the Reader interface. The Reader interface is defined as follows.

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

The Reader interface's method set (Method_sets) contains *only one Read method*, so all types that implement the Read method satisfy the io.Reader interface, that is, instances of types that implement the Read() method can be passed wherever io.Reader is required.

Below, let's talk about the usage of this interface through specific examples.

```go
    func ReadFrom(reader io.Reader, num int) ([]byte, error) {
        p := make([]byte, num)
        n, err := reader.Read(p)
        if n > 0 {
            return p[:n], nil
        }
        return p, err
    }
```

Reader as an argument, i.e., ReadFrom can read data from anywhere, as long as the source implements the io.Reader interface. For example, we can read data from standard inputs, files, strings, etc. The example code is as follows.

```go
data, err = ReadFrom(os.Stdin, 11)
data, err = ReadFrom(file, 9)
data, err = ReadFrom(strings.NewReader("from string"), 12)
```

So you can do things like:

```go
package main                                                                                                         
                                                                                                                     
import (                                                                                                             
        "fmt"                                                                                                        
        "io"                                                                                                         
        "os"                                                                                                         
)                                                                                                                    
                                                                                                                     
func ReadFrom(reader io.Reader, num int) ([]byte, error) {                                                           
        p := make([]byte, num)                                                                                       
        n, err := reader.Read(p)                                                                                     
        if n > 0 {                                                                                                   
                return p[:n], nil                                                                                    
        }                                                                                                            
        return p, err                                                                                                
}                                                                                                                    
                                                                                                                     
func main() {                                                                                                        
   fmt.Println("Hello, World!")                                                                                      
                                                                                                                     
   // read from terminal                                                                                             
   data, err := ReadFrom(os.Stdin, 11)                                                                               
   if err != nil {                                                                                                   
       fmt.Println(data)                                                                                             
   }                                                                                                                 
                                                                                                                     
   // read from file                                                                                                 
   file, err := os.Open("./z.go")                                                                                    
   if err != nil {                                                                                                   
        fmt.Println("Error opening file:", err)                                                                      
   }                                                                                                                 
   data, err = ReadFrom(file, 9)                                                                                     
   fmt.Println(data)                                                                                                 
   file.Close()                                                                                                      
}                                                                                                                    
```        

**Related links:**
* <a href="https://golangr.com/">Golang tutorial</a>
* <a href="https://tour.golang.org/methods/21">Another reader example</a>