Skip to content

Instantly share code, notes, and snippets.

@16892434
Forked from lovasoa/read_gzip_lines.go
Created October 14, 2022 08:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 16892434/69d87d66dfc3e8ab739ec2d4d6b7f136 to your computer and use it in GitHub Desktop.
Save 16892434/69d87d66dfc3e8ab739ec2d4d6b7f136 to your computer and use it in GitHub Desktop.
How to Read Lines from GZIP-Compressed Files in Go
package main
import (
"bufio"
"compress/gzip"
"fmt"
"io"
"log"
"os"
)
// GZLines iterates over lines of a file that's gzip-compressed.
// Iterating lines of an io.Reader is one of those things that Go
// makes needlessly complex.
func GZLines(rawf io.Reader) (chan []byte, chan error, error) {
rawContents, err := gzip.NewReader(rawf)
if err != nil {
return nil, nil, err
}
bufferedContents := bufio.NewReader(rawContents)
ch := make(chan []byte)
errs := make(chan error)
go func(ch chan []byte, errs chan error, contents *bufio.Reader) {
defer func(ch chan []byte, errs chan error) {
close(ch)
close(errs)
}(ch, errs)
for {
line, err := contents.ReadBytes('\n')
ch <- line
if err != nil {
if err != io.EOF {
errs <- err
}
return
}
}
}(ch, errs, bufferedContents)
return ch, errs, nil
}
func main() {
if len(os.Args) < 2 {
log.Fatal("Usage: read file.gz")
}
filename := os.Args[1]
fmt.Printf("Called on: %+v\n", filename)
rawf, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
lines, errors, err := GZLines(rawf)
if err != nil {
log.Fatal(err)
}
for {
select {
case line := <-lines:
os.Stdout.Write(line)
case err := <-errors:
log.Fatal(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment