Communication

Good communication is as stimulating as black coffee, and just as hard to sleep after.


– Anne Morrow Lindbergh

In this chapter we are going to look at the building blocks in Go forcommunicating with the outside world. We will look at files, directories,networking and executing other programs. Central to Go’s I/O are the interfacesio.Reader and io.Writer. The io.Reader interface specifies one methodRead(p []byte) (n int, err err).

Reading from (and writing to) files is easy in Go. This programonly uses the os package to read data from the file /etc/passwd.

  1. package main
  2. import (
  3. "log"
  4. "os"
  5. )
  6. func main() {
  7. buf := make([]byte, 1024)
  8. f, e := os.Open("/etc/passwd") 1
  9. if e != nil {
  10. log.Fatalf(e)
  11. }
  12. defer f.Close() 2
  13. for {
  14. n, e := f.Read(buf) 3
  15. if e != nil {
  16. log.Fatalf(e) 4
  17. }
  18. if n == 0 { 5
  19. break
  20. }
  21. os.Stdout.Write(buf[:n]) 6
  22. }
  23. }

We open the file at 1 with os.Open that returns a os.Fileos.File implements io.Reader and io.Writer interface.After the Open we directly put the f.Close() which we defer until the functionreturn. At 3 we call Read on f and read up to 1024 bytes at the time. If anythingfails we bail out at 4. If the number of bytes read is 0 we’ve read the end of thefile 5. And at 6 we output the buffer to standard output.

If you want to use buffered I/O there is thebufio package:

  1. package main
  2. import (
  3. "bufio"
  4. "log"
  5. "os"
  6. )
  7. func main() {
  8. buf := make([]byte, 1024)
  9. f, e := os.Open("/etc/passwd") 1
  10. if e != nil {
  11. log.Fatalf(e)
  12. }
  13. defer f.Close()
  14. r := bufio.NewReader(f) 2
  15. w := bufio.NewWriter(os.Stdout)
  16. defer w.Flush() 3
  17. for {
  18. n, e := r.Read(buf) 4
  19. if e != nil {
  20. log.Fatalf(e)
  21. }
  22. if n == 0 {
  23. break
  24. }
  25. w.Write(buf[0:n]) 5
  26. }
  27. }

Again, we open 1 the file. Then at 2 weTurn f into a buffered Reader. NewReader expects an io.Reader, so you this will work.Then at 4 we read and at 5 we write. We also call Flush() at 3 to flush all output.This entire program could be optimized further by using io.Copy.