In this post, we are going to take a look at how to tar and untar files and how to zip and unzip using gzip in Golang.
What is tarring and gzipping?
The tar is an archive which joins all the file together into a tar file. It is an archiving algorithm.
The gzip function, on the other hand, is a compression algorithm. It reduces file size greatly, especially for text files.
Required imports
We are going to use tar and gzip package in Go. So, the imports will be:
import (
"archive/tar"
"compress/gzip"
)
1. Tarring and untarring files
Now, we are going to use the function shown below to tar a source into a tar archive. The tar package provides ways to do so.
func Tar(source, target string) error {
filename := filepath.Base(source)
target = filepath.Join(target, fmt.Sprintf("%s.tar", filename))
tarfile, err := os.Create(target)
if err != nil {
return err
}
defer tarfile.Close()
tarball := tar.NewWriter(tarfile)
defer tarball.Close()
info, err := os.Stat(source)
if err != nil {
return nil
}
var baseDir string
if info.IsDir() {
baseDir = filepath.Base(source)
}
return filepath.Walk(source,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
header, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return err
}
if baseDir != "" {
header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
}
if err := tarball.WriteHeader(header); err != nil {
return err
}
if info.IsDir() {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(tarball, file)
return err
})
}
Now, the usage of the fund will be:
Tar("file/or/directory/path", "destination/path")
This will produce a .tar file. Now to untar it we will use the function below:
func Untar(tarball, target string) error {
reader, err := os.Open(tarball)
if err != nil {
return err
}
defer reader.Close()
tarReader := tar.NewReader(reader)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
} else if err != nil {
return err
}
path := filepath.Join(target, header.Name)
info := header.FileInfo()
if info.IsDir() {
if err = os.MkdirAll(path, info.Mode()); err != nil {
return err
}
continue
}
file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, tarReader)
if err != nil {
return err
}
}
return nil
}
2. Zipping files with Gzip
The gzip package offers the way to do gzip. Here are the functions for gzip and unzipping just like before.
func Gzip(source, target string) error {
reader, err := os.Open(source)
if err != nil {
return err
}
filename := filepath.Base(source)
target = filepath.Join(target, fmt.Sprintf("%s.gz", filename))
writer, err := os.Create(target)
if err != nil {
return err
}
defer writer.Close()
archiver := gzip.NewWriter(writer)
archiver.Name = filename
defer archiver.Close()
_, err = io.Copy(archiver, reader)
return err
}
func UnGzip(source, target string) error {
reader, err := os.Open(source)
if err != nil {
return err
}
defer reader.Close()
archive, err := gzip.NewReader(reader)
if err != nil {
return err
}
defer archive.Close()
target = filepath.Join(target, archive.Name)
writer, err := os.Create(target)
if err != nil {
return err
}
defer writer.Close()
_, err = io.Copy(writer, archive)
return err
}
This two functions can be used the same as previous ones:
Gzip("file/or/directory/path", "destination/path")
Uses of tar and gzip
These two are some of the most used techniques all over the internet. The gzip is a very balanced compression algorithm and the tar is a very efficient archiving algorithm.