Working with the io package

The obvious place to start with IO is, well, the io package (https://golang.org/pkg/io). As we have already seen, the io package defines input and output primitives as the io.Reader and io.Writer interfaces. The following table summarizes additional functions and types, available in the io package, that facilitate streaming IO operations.

Function

Description

io.Copy()

The io.Copy function (and its variants io.CopyBuffer and io.CopyN) make it easy to copy data from an arbitrary io.Reader source into an equally arbitrary io.Writer sink as shown in the following snippet:

data := strings.NewReader("Write   me down.")   
file, _ := os.Create("./iocopy.data")   
io.Copy(file, data)   

golang.fyi/ch10/iocopy.go

PipeReader PipeWriter

The io package includes the PipeReader and PipeWriter types that model IO operations as an in-memory pipe. Data is written to the pipe's io.Writer and can independently be read at the pipe's io.Reader. The following abbreviated snippet illustrates a simple pipe that writes a string to the writer pw. The data is then consumed with the pr reader and copied to a file:

file, _ := os.Create("./iopipe.data")   
pr, pw := io.Pipe()    
go func() {   
    fmt.Fprint(pw, "Pipe   streaming")   
    pw.Close()   
}()   
   
wait := make(chan struct{})   
go func() {   
    io.Copy(file, pr)   
    pr.Close()   
    close(wait)   
}()   
<-wait //wait for pr to finish   

golang.fyi/ch10/iopipe.go

Note that the pipe writer will block until the reader completely consumes the pipe content or an error is encountered. Therefore, both the reader and writer should be wrapped in a goroutine to avoid deadlocks.

io.TeeReader()

Similar to the io.Copy function, io.TeeReader transfers content from a reader to a writer. However, the function also emits the copied bytes (unaltered) via a returned io.Reader.

The TeeReader works well for composing multi-step IO stream processing. The following abbreviated snippet first calculates the SHA-1 hash of a file content using the TeeReader. The resulting reader, data, is then streamed to a gzip writer zip:

fin, _ := os.Open("./ioteerdr.go")   
defer fin.Close()   
fout, _ := os.Create("./teereader.gz")   
defer fout.Close()   
   
zip := gzip.NewWriter(fout)   
defer zip.Close()   
sha := sha1.New()   
data := io.TeeReader(fin, sha)    
io.Copy(zip, data)   
   
fmt.Printf("SHA1 hash %x
",   sha.Sum(nil))   

golang.fyi/ch10/ioteerdr0.go

If we wanted to calculate both SHA-1 and MD5, we can update the code to nest the two TeeReader values as shown in the following snippet:

sha := sha1.New()   
md := md5.New()   
data := io.TeeReader(
  io.TeeReader(fin, md), sha,   
)    
io.Copy(zip, data)   

golang.fyi/ch10/ioteerdr1.go

io.WriteString()

The io.WriteString function writes the content of string into a specified writer. The following writes the content of a string to a file:

fout, err := os.Create("./iowritestr.data")   
if err != nil {   
    fmt.Println(err)   
    os.Exit(1)   
}   
defer fout.Close()   
io.WriteString(fout, "Hello   there!
")   

golang.fyi/ch10/iowritestr.go

io.LimitedReader

As its name suggests, the io.LimitedReader struct is a reader that reads only N number of bytes from the specified io.Reader. The following snippet will print the first 19 bytes from the string:

str := strings.NewReader("The   quick brown " +       
    "fox jumps over the lazy   dog")   
limited :=   &io.LimitedReader{R: str, N: 19}   
io.Copy(os.Stdout, limited)   

golang.fyi/ch10/iolimitedrdr.go

$> go run iolimitedrd.go   
The quick brown fox   

io.SectionReader

The io.SectionReader type implements seek and skip primitives by specifying an index (zero-based) where to start reading and an offset value indicating the number of bytes to read as shown in the following snippet:

str := strings.NewReader("The   quick brown"+   
    "fox jumps over the lazy   dog")   
section := io.NewSectionReader(str,   19, 23)   
io.Copy(os.Stdout, section)   

golang.fyi/ch10/iosectionrdr.go

This example will print jumps over the lazy dog.

Package io/ioutil

The io/ioutil sub-package implements a small number of functions that provide utilitarian shortcuts to IO primitives such as file read, directory listing, temp directory creation, and file write.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.179.85