Skip to content

Instantly share code, notes, and snippets.

@qbig
Created August 14, 2018 12:26
Show Gist options
  • Select an option

  • Save qbig/0682f81a7efc1be27315f66fe107f49e to your computer and use it in GitHub Desktop.

Select an option

Save qbig/0682f81a7efc1be27315f66fe107f49e to your computer and use it in GitHub Desktop.
Using the common I/O interfaces

The io.Reader and io.Writer interfaces

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

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

Combine interfaces

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

type ReadSeeker interface {
        Reader
        Seeker
}

io.Pipe()

func Pipe() (*PipeReader, *PipeWriter)

Example

        package interfaces

        import (
                "fmt"
                "io"
                "os"
        )

        // Copy copies data from in to out first directly,
        // then using a buffer. It also writes to stdout
        func Copy(in io.ReadSeeker, out io.Writer) error {
                // we write to out, but also Stdout
                w := io.MultiWriter(out, os.Stdout)

                // a standard copy, this can be dangerous if there's a 
                // lot of data in in
                if _, err := io.Copy(w, in); err != nil {
                    return err
                }

                in.Seek(0, 0)

                // buffered write using 64 byte chunks
                buf := make([]byte, 64)
                if _, err := io.CopyBuffer(w, in, buf); err != nil {
                    return err
                }

                // lets print a new line
                fmt.Println()

                return nil
        }
      package interfaces

        import (
                "io"
                "os"
        )

        // PipeExample helps give some more examples of using io  
        //interfaces
        func PipeExample() error {
                // the pipe reader and pipe writer implement
                // io.Reader and io.Writer
                r, w := io.Pipe()

                // this needs to be run in a separate go routine
                // as it will block waiting for the reader
                // close at the end for cleanup
                go func() {
                    // for now we'll write something basic,
                    // this could also be used to encode json
                    // base64 encode, etc.
                    w.Write([]byte("testn"))
                    w.Close()
                }()

                if _, err := io.Copy(os.Stdout, r); err != nil {
                    return err
                }
                return nil
        }
        package main

        import (
             "bytes"
             "fmt"

             "github.com/agtorre/go-cookbook/chapter1/interfaces"
        )

        func main() {
                in := bytes.NewReader([]byte("example"))
                out := &bytes.Buffer{}
                fmt.Print("stdout on Copy = ")
                if err := interfaces.Copy(in, out); err != nil {
                        panic(err)
                }

                fmt.Println("out bytes buffer =", out.String())

                fmt.Print("stdout on PipeExample = ")
                if err := interfaces.PipeExample(); err != nil {
                        panic(err)
                }
        }
@qbig
Copy link
Author

qbig commented Aug 14, 2018

        $ go run main.go
        stdout on Copy = exampleexample
        out bytes buffer = exampleexample
        stdout on PipeExample = test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment