golang并发计算大文件md5效率优化提供代码
以下是一个并发计算大文件 MD5 值的示例代码:
package main
import (
"crypto/md5"
"fmt"
"io"
"os"
"path/filepath"
"runtime"
"sync"
)
const chunkSize = 1024 * 1024 // 每个协程处理的块大小为 1MB
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) // 设置使用的 CPU 核心数
if len(os.Args) < 2 {
fmt.Println("Usage: go run md5sum.go <file>")
os.Exit(1)
}
file, err := os.Open(os.Args[1])
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if fileInfo.IsDir() {
fmt.Println("Error: directory is not supported")
os.Exit(1)
}
var wg sync.WaitGroup
var result [16]byte // MD5 值为 16 字节长
chunkCount := (fileInfo.Size() + chunkSize - 1) / chunkSize // 计算需要的协程数
for i := int64(0); i < chunkCount; i++ {
start := i * chunkSize
end := (i + 1) * chunkSize
if end > fileInfo.Size() {
end = fileInfo.Size()
}
chunk := make([]byte, end-start)
_, err := file.ReadAt(chunk, start)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
wg.Add(1)
go func(data []byte) {
defer wg.Done()
md5sum := md5.Sum(data)
for i := range md5sum {
result[i] ^= md5sum[i] // 将每个协程计算出的 MD5 值合并
}
}(chunk)
}
wg.Wait()
fmt.Printf("%s %s\n", fmt.Sprintf("%x", result[:]), filepath.Base(os.Args[1]))
}
该代码使用了 Go 语言的并发特性,将大文件分成若干块,每块交由一个协程计算 MD5 值,最后将每个协程计算出的 MD5 值合并得到最终的 MD5 值。通过并发计算,可以大幅提高计算效率。

原文地址: http://www.cveoy.top/t/topic/49V 著作权归作者所有。请勿转载和采集!