diff --git a/interfaces/14-io-reusable/main.go b/interfaces/14-io-reusable/main.go index 0f24f09..391698c 100644 --- a/interfaces/14-io-reusable/main.go +++ b/interfaces/14-io-reusable/main.go @@ -9,38 +9,44 @@ package main import ( - "bytes" - "fmt" "io" "log" "os" ) -// you can download the rosie.unknown image in the link: -// https://inancgumus.github.com/x/rosie.unknown - -// then feed the file to the standard input of this program: -// go run . < rosie.unknown - func main() { - const pngSign = "\x89PNG\r\n\x1a\n" - const pngSignLen = 8 - - // create an in-memory buffer (bytes.Buffer is an io.Reader and an io.Writer). - memory := bytes.Buffer{} - // stream from the standard input to the in-memory buffer in 32KB data chunks. - // os.Stdin.Read(...) -> memory.Write(...) - if _, err := io.Copy(&memory, os.Stdin); err != nil { + // os.Stdin.Read(...) -> os.Stdout.Write(...) + if _, err := io.Copy(os.Stdout, os.Stdin); err != nil { log.Fatal(err) } - - // get the accumulated bytes from the in-memory buffer. - buf := memory.Bytes() - - // print the first eight bytes. - fmt.Printf("% x\n", buf[:pngSignLen]) - - // compare it with the png signature. - fmt.Printf("% x\n", pngSign) +} + +// ioCopy streams from a file to another file. +// we use it to stream from the standard input to ouput. +func ioCopy(dst, src *os.File) error { + // Use a fixed-length buffer to efficiently read from src stream in chunks. + buf := make([]byte, 32768) + + // read over and over again to read all the data. + for { + // read can read only up to the buffer length. + nr, er := src.Read(buf) + // only write data if there is something to write. + if nr > 0 { + _, ew := dst.Write(buf[:nr]) + if ew != nil { + return ew + } + } + // io.EOF = there is nothing left to read—close the loop. + if er == io.EOF { + return nil + } + // Only return an error if the reading really fails. + if er != nil { + return er + } + } + return nil } diff --git a/interfaces/15-png-detector/main.go b/interfaces/15-png-detector/main.go new file mode 100644 index 0000000..690d63d --- /dev/null +++ b/interfaces/15-png-detector/main.go @@ -0,0 +1,53 @@ +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// +// For more tutorials : https://learngoprogramming.com +// In-person training : https://www.linkedin.com/in/inancgumus/ +// Follow me on twitter: https://twitter.com/inancgumus + +package main + +import ( + "bytes" + "fmt" + "io" + "log" + "net/http" +) + +// you can download the rosie.unknown image in the link: +// https://inancgumus.github.com/x/rosie.unknown + +// then feed the file to the standard input of this program: +// go run . < rosie.unknown + +func main() { + const pngSign = "\x89PNG\r\n\x1a\n" + const pngSignLen = 8 + + // create an in-memory buffer (bytes.Buffer is an io.Reader and an io.Writer). + memory := bytes.Buffer{} + + // get it from the web server + resp, err := http.Get("https://inancgumus.github.com/x/rosie.unknown") + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + + // stream from the standard input to the in-memory buffer in 32KB data chunks. + // os.Stdin.Read(...) -> memory.Write(...) + if _, err := io.Copy(&memory, resp.Body); err != nil { + log.Fatal(err) + } + + // get the accumulated bytes from the in-memory buffer. + buf := memory.Bytes() + + // print the first eight bytes. + fmt.Printf("% x\n", buf[:pngSignLen]) + + // compare it with the png signature. + fmt.Printf("% x\n", pngSign) +}