這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
package mainimport ( "bufio" "bytes" "flag" "fmt" "io" "log" "net/http" "os" "path/filepath" "strings" "github.com/czxichen/AutoWork/tools/md5" "github.com/czxichen/AutoWork/tools/split")var ( raddr, laddr string sdir, ddir, exclude string passName []string result string = "result/")func init() { flag.StringVar(&ddir, "d", "", "-d 指定要匹配的目錄") flag.StringVar(&sdir, "s", "", "-s 指定要讀取的目錄") flag.StringVar(&raddr, "p", "", "-p 指定原始目錄的IP和連接埠") flag.StringVar(&laddr, "l", ":1789", "-l 127.0.0.1:1789 指定監聽的連接埠") flag.StringVar(&exclude, "v", "", "-v log,txt 指定排除的尾碼檔案") flag.Parse()}func main() { if sdir != "" && laddr != "" { Server() return } if ddir != "" && raddr != "" { Client(raddr) return } flag.Usage()}func Server() { sdir = filepath.ToSlash(sdir) if !strings.HasSuffix(sdir, "/") { sdir += "/" } if exclude != "" { passName = strings.Split(exclude, ",") } os.MkdirAll(result, 0666) Walk(sdir) http.HandleFunc("/", Router) http.ListenAndServe(laddr, nil)}func Router(w http.ResponseWriter, r *http.Request) { log.Printf("遠端地址:%s\t訪問的路徑:%s\n", r.RemoteAddr, r.URL.Path) defer r.Body.Close() switch r.URL.Path { case "/": File, err := os.Open("md5_list.txt") if err != nil { http.NotFound(w, r) return } io.Copy(w, File) File.Close() case "/result": file, err := os.Create(result + strings.Split(r.RemoteAddr, ":")[0] + ".txt") if err != nil { http.Error(w, err.Error(), 501) return } io.Copy(file, r.Body) file.Close() case "/flushmd5": Walk(sdir) fmt.Fprintln(w, "flush md5 list ok") }}func Walk(dir string) { File, err := os.Create("md5_list.txt") if err != nil { log.Println("建立md5列表檔案失敗:", err.Error()) return } defer File.Close() err = filepath.Walk(dir, func(root string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } if Exclude(root) { return nil } m5, err := md5.Md5(root) if err != nil { log.Printf("讀取檔案:%s的md5失敗,錯誤資訊:\n", root, err.Error()) return err } root = strings.TrimPrefix(filepath.ToSlash(root), dir) fmt.Fprintln(File, root, m5) return nil }) if err != nil { log.Println("遍曆檔案夾出錯:", err.Error()) } log.Println("遍曆擷取md5完成")}func Exclude(Suffix string) bool { for _, name := range passName { if strings.HasSuffix(Suffix, name) { return true } } return false}func Client(ip string) { ddir = filepath.ToSlash(ddir) if !strings.HasSuffix(ddir, "/") { ddir += "/" } resp, err := http.Get("http://" + ip) if err != nil { fmt.Println("串連遠端出錯:", err.Error()) return } buf := bytes.NewBuffer(nil) io.Copy(buf, resp.Body) resp.Body.Close() File, err := os.Create("cmd5_list.txt") if err != nil { fmt.Println("建立結果檔案失敗:", err.Error()) return } defer File.Close() err = Compare(buf, File, ddir) if err != nil { fmt.Println(err) } File.Sync() File.Seek(0, 0) err = client(File, ip) if err != nil { fmt.Println("上傳結果出錯:", err.Error()) } os.Remove("cmd5_list.txt")}func Compare(r io.Reader, w io.Writer, dst string) error { rd := bufio.NewReader(r) for { line, _, err := rd.ReadLine() if err != nil { if err == io.EOF { break } return err } path_md5 := split.Split(string(line)) if len(path_md5) != 2 { continue } m5, err := md5.Md5(dst + path_md5[0]) if err != nil { if os.IsNotExist(err) { fmt.Fprintln(w, path_md5[0], path_md5[1], "'File_not_is_exist'") } else { fmt.Fprintln(w, path_md5[0], path_md5[1], err.Error()) } continue } if path_md5[1] != m5 { fmt.Fprintln(w, path_md5[0], path_md5[1], m5) } } return nil}func client(r io.Reader, ip string) error { resp, err := http.Post("http://"+ip+"/result", "application/octet-stream", r) if err != nil { return err } resp.Body.Close() return nil}