Fragment Description:



Article by Samir Ajmani, see here:http://blog.golang.org/pipelines Go's concurrency primitives make it easy to construct streaming data pipelines that make efficient use of I/O and multiple CPUs.
This article presents examples of such pipelines, highlights subtleties that arise when operations fail, and introduces techniques for dealing with failures cleanly.
A must read along with the article about Context:http://blog.golang.org/context


streamingInSerial

Go Playground

Last update, on 2015, Fri 9 Oct, 16:15:30

/* ... <== see fragment description ... */

package main

import (
    "crypto/md5"
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "path/filepath"
    "sort"
    "strconv"
    "time"
)

// MD5All reads all the files in the file tree rooted at root and returns a
// map
// from file path to the MD5 sum of the file's contents.  If the directory
// walk
// fails or any read operation fails, MD5All returns an error.
func MD5All(root string) (map[string][md5.Size]byte, error) {
    m := make(map[string][md5.Size]byte)
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { // HL
        if err != nil {
            return err
        }
        if info.IsDir() {
            return nil
        }
        data, err := ioutil.ReadFile(path) // HL
        if err != nil {
            return err
        }
        m[path] = md5.Sum(data) // HL
        return nil
    })
    if err != nil {
        return nil, err
    }
    return m, nil
}
func main() {
    defer timeTrack(time.Now(), "task duration:")
    // Calculate the MD5 sum of all files under the specified directory,
    // then print the results sorted by path name.
    // m, err := MD5All(os.Args[1]) // HL
    m, err := MD5All("./")
    if err != nil {
        fmt.Println(err)
        return
    }
    var paths []string
    for path := range m {
        paths = append(paths, path)
    }
    sort.Strings(paths) // HL
    for _, path := range paths {
        fi, err := os.Stat(path)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%x\t%q\t--> Size= %q bytes.\n", m[path], path, strconv.FormatInt(fi.Size(), 10))
    }
}

// /////////utility functions /////
func timeTrack(start time.Time, name string) {
    elapsed := time.Since(start)
    fmt.Printf("function %s took %v\n", name, elapsed)
}

/*  Expected Output:
fd744a197489c10b33494c3884c3d0ad   "serial.exe"  --> Size= "2393600" bytes.
332827025c8f219793dc44df08d0ac40   "serial.go"   --> Size= "1544" bytes.
function task duration: took 6.0003ms
*/



Comments