Golang : untar or extract tar ball archive example
Many system administrators like to use the tar
program to archive the entire directory and gzip
to compress newly created tar ball for backup purpose or FTP to another server for batch processing purpose.
There are times when a program sitting on one server will receive tar balls from another or multiple servers. The 'traditional' way is to untar the files with shell scripts and then process the untarred files. Since this tutorial focus on is on Golang, we will explore how to untar
the compressed tar ball with Golang.
The codes below will demonstrate how to untar files with Golang.
go-untar.go
package main
import (
"archive/tar"
"compress/gzip"
"flag"
"fmt"
"io"
"os"
"strings"
)
func main() {
flag.Parse() // get the arguments from command line
sourcefile := flag.Arg(0)
if sourcefile == "" {
fmt.Println("Usage : go-untar sourcefile.tar")
os.Exit(1)
}
file, err := os.Open(sourcefile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
var fileReader io.ReadCloser = file
// just in case we are reading a tar.gz file, add a filter to handle gzipped file
if strings.HasSuffix(sourcefile, ".gz") {
if fileReader, err = gzip.NewReader(file); err != nil {
fmt.Println(err)
os.Exit(1)
}
defer fileReader.Close()
}
tarBallReader := tar.NewReader(fileReader)
// Extracting tarred files
for {
header, err := tarBallReader.Next()
if err != nil {
if err == io.EOF {
break
}
fmt.Println(err)
os.Exit(1)
}
// get the individual filename and extract to the current directory
filename := header.Name
switch header.Typeflag {
case tar.TypeDir:
// handle directory
fmt.Println("Creating directory :", filename)
err = os.MkdirAll(filename, os.FileMode(header.Mode)) // or use 0755 if you prefer
if err != nil {
fmt.Println(err)
os.Exit(1)
}
case tar.TypeReg:
// handle normal file
fmt.Println("Untarring :", filename)
writer, err := os.Create(filename)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
io.Copy(writer, tarBallReader)
err = os.Chmod(filename, os.FileMode(header.Mode))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
writer.Close()
default:
fmt.Printf("Unable to untar type : %c in file %s", header.Typeflag, filename)
}
}
}
Sample output :
./go-untar testdir.tar (non gzip)
Creating directory : ./testdir/
Untarring : ./testdir/dumb3.txt
./go-untar testdir.tar.gz
Creating directory : ./testdir/
Untarring : ./testdir/dumb3.txt
See also : Golang : Archive directory with tar and gzip
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+36.6k Golang : Display float in 2 decimal points and rounding up or down
+18k Golang : Convert IPv4 address to decimal number(base 10) or integer
+10.5k RPM : error: db3 error(-30974) from dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
+5k Linux/Unix/MacOSX : Find out which application is listening to port 80 or use which IP version
+21.5k Golang : Encrypt and decrypt data with TripleDES
+21.7k Golang : Setting up/configure AWS credentials with official aws-sdk-go
+4.4k Java : Generate multiplication table example
+9.2k Golang : How to control fmt or log print format?
+25.6k Golang : How to write CSV data to file
+8.7k Golang : Heap sort example
+13.9k Golang : How to check if a file is hidden?
+16.1k Golang : How to check if input from os.Args is integer?