要求用go实现 1、实现一个md5file的工具,通过命令行获取目录路径,计算路径下所有文 件的md5值,包括递归文件夹。 要求: a、需要使用协程并发计算每个文件的md5值,提升计算效率。 b、考虑文件或者文件夹在权限不够的情况下,能够跳过权限不够的地方, 继续计算其他的,而不是中途退出。
时间: 2024-03-27 14:38:52 浏览: 10
好的,我了解你的需求了。以下是使用Go语言实现的md5file工具代码,满足你的要求:
```go
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
)
func md5file(path string, wg *sync.WaitGroup, ch chan<- string) {
defer wg.Done()
file, err := os.Open(path)
if err != nil {
fmt.Printf("Failed to open file %s: %s\n", path, err.Error())
return
}
defer file.Close()
info, err := file.Stat()
if err != nil {
fmt.Printf("Failed to get file info for %s: %s\n", path, err.Error())
return
}
if info.IsDir() {
return // Skip directories
}
hash := md5.New()
if _, err := io.Copy(hash, file); err != nil {
fmt.Printf("Failed to calculate md5 for %s: %s\n", path, err.Error())
return
}
md5sum := hex.EncodeToString(hash.Sum(nil))
ch <- fmt.Sprintf("%s %s", md5sum, path)
}
func main() {
if len(os.Args) < 2 {
fmt.Printf("Usage: %s [directory]\n", os.Args[0])
return
}
root := os.Args[1]
var wg sync.WaitGroup
ch := make(chan string)
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Printf("Failed to walk path %s: %s\n", path, err.Error())
return nil
}
if info.Mode().IsRegular() { // Only process regular files
wg.Add(1)
go md5file(path, &wg, ch)
}
return nil
})
if err != nil {
fmt.Printf("Failed to walk directory %s: %s\n", root, err.Error())
return
}
go func() {
wg.Wait()
close(ch) // All files have been processed
}()
for result := range ch {
fmt.Println(result)
}
}
```
该程序使用了协程并发计算每个文件的md5值,提高了计算效率。在处理文件或者文件夹权限不够的情况下,该程序会跳过权限不够的地方,继续计算其他的,而不是中途退出。