Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fhefh2015/acd2ace72bdf8b274d1c63d48882d72b to your computer and use it in GitHub Desktop.
Save fhefh2015/acd2ace72bdf8b274d1c63d48882d72b to your computer and use it in GitHub Desktop.
package main

import (
	"crypto/md5"
	//"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	//"sort"
	"runtime"
	"sync"
	"time"
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	startTime := time.Now()
	resultArr := MD5All("/home/zl/.gvm/")
	endTime := time.Now()
	fmt.Println(endTime.Sub(startTime))
	fmt.Println(len(resultArr))
}

type Result struct {
	Path    string
	Md5byte [md5.Size]byte
	Err     error
}

//get file path then set file path to chan
func Walk(chanIn chan<- string, root string) {

	go func() {
		filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}

			if !info.Mode().IsRegular() {
				return nil
			}

			chanIn <- path
			return nil
		})
		close(chanIn)
	}()
}

func doMd5(chanPath chan string, chanOut chan<- *Result) {
	var wg sync.WaitGroup

	for path := range chanPath {
		wg.Add(1)
		go func() {
			data, _ := ioutil.ReadFile(path)
			result := &Result{Path: path, Md5byte: md5.Sum(data)}
			chanOut <- result
			wg.Done()
		}()
	}
	go func() {
		wg.Wait()
		close(chanOut)
	}()
}

func MD5All(rootPath string) []*Result {
	resultArr := make([]*Result, 10)
	chanPath := make(chan string)
	Walk(chanPath, rootPath)

	chanResult := make(chan *Result)
	doMd5(chanPath, chanResult)

	for result := range chanResult {
		resultArr = append(resultArr, result)
	}

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