package main
import (
"fmt"
"io/ioutil"
"path/filepath"
"sync"
)
func CompressImages(imagePaths []string, outputDir string) error {
var wg sync.WaitGroup
var mu sync.Mutex
errChan := make(chan error, len(imagePaths))
for _, path := range imagePaths {
wg.Add(1)
go func(p string) {
defer wg.Done()
img, err := ioutil.ReadFile(p)
if err != nil {
errChan <- err
return
}
compressedImg, err := CompressImage(img)
if err != nil {
errChan <- err
return
}
outputPath := filepath.Join(outputDir, filepath.Base(p))
mu.Lock()
err = ioutil.WriteFile(outputPath, compressedImg, 0644)
mu.Unlock()
if err != nil {
errChan <- err
return
}
}(path)
}
go func() {
wg.Wait()
close(errChan)
}()
for err := range errChan {
if err != nil {
return err
}
}
return nil
}
func CompressImage(img []byte) ([]byte, error) {
// 这里是实际的图片压缩逻辑,省略具体实现
return img, nil
}
- 并发处理:通过
go
关键字启动多个协程并行处理每张图片的压缩任务。
- 错误处理:使用
errChan
通道来收集每个协程中的错误,如果有错误发生,主函数可以及时返回错误。
- 资源竞争:使用
sync.Mutex
互斥锁来保护对文件写入操作,避免多个协程同时写入文件导致的数据竞争问题。
- 等待所有任务完成:使用
sync.WaitGroup
来等待所有协程完成任务后再关闭errChan
通道,确保主函数不会提前返回。