Go言語で並列でのファイル圧縮解除圧縮を処理する方法
Go言語で並列ファイルの圧縮・解凍問題を処理するには、goroutineとチャネルを使用して実装できます。
ファイルを読み込むには、ioパッケージを使用し、読み込んだデータをチャンネルに送信できます。同時に、sync.WaitGroupを使用して、すべてのファイル読み取り操作が完了するのを待機できます。
func readFile(filename string, ch chan<- []byte, wg *sync.WaitGroup) {
defer wg.Done()
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
data, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
ch <- data
}
gzipファイルの圧縮と解凍処理には、compress/gzipパッケージを利用できます。それぞれの処理をgoroutineで実行し、2つのチャネルでデータの受け渡しを行うことで、並行処理を可能にします。
func compressData(data []byte, ch chan<- []byte) {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
if _, err := gz.Write(data); err != nil {
log.Fatal(err)
}
if err := gz.Close(); err != nil {
log.Fatal(err)
}
ch <- buf.Bytes()
}
func decompressData(data []byte, ch chan<- []byte) {
buf := bytes.NewReader(data)
gz, err := gzip.NewReader(buf)
if err != nil {
log.Fatal(err)
}
defer gz.Close()
decompressed, err := ioutil.ReadAll(gz)
if err != nil {
log.Fatal(err)
}
ch <- decompressed
}
最後に、並行のファイル圧縮と解凍プロセスを実現するために以下の方法を使用できます。
func main() {
// 读取文件
files := []string{"file1.txt", "file2.txt", "file3.txt"}
ch := make(chan []byte)
var wg sync.WaitGroup
for _, file := range files {
wg.Add(1)
go readFile(file, ch, &wg)
}
go func() {
wg.Wait()
close(ch)
}()
// 压缩文件
compressedCh := make(chan []byte)
for i := 0; i < len(files); i++ {
data := <-ch
go compressData(data, compressedCh)
}
go func() {
wg.Wait()
close(compressedCh)
}()
// 解压缩文件
decompressedCh := make(chan []byte)
for i := 0; i < len(files); i++ {
compressedData := <-compressedCh
go decompressData(compressedData, decompressedCh)
}
go func() {
wg.Wait()
close(decompressedCh)
}()
// 处理解压缩后的数据
for i := 0; i < len(files); i++ {
decompressedData := <-decompressedCh
// 处理解压缩后的数据
fmt.Println(string(decompressedData))
}
}
ファイルデータのやり取りに使うチャネルをまず作ります。そして、すべてのファイル読み込み処理が終了するまでsync.WaitGroupを使って待ちます。読み込み処理が終了したら、チャネルを閉じます。
次に圧縮したデータを渡すチャネルを作成しました。すべてのファイルデータを処理するループを使用し、圧縮したデータをチャネルに送信します。同様に sync.WaitGroup を使用して、すべての圧縮操作が完了するのを待ってから、完了後にチャネルを閉じます。
最後に、デコードしたデータを送信するチャンネルを作成しました。すべての圧縮データを処理するループを使用し、デコードしたデータをそのチャンネルに送信します。同様に、すべてのデコード操作が完了するのを待ち、完了したらそのチャンネルを閉じます。
最後にデコード済みデータチャネルからデータを読み取り、デコードデータを処理する。上のサンプルでは、デコードデータを単純に出力する処理をしているが、実際の用途に応じて、デコードデータの処理をカスタマイズすることができる。