Golang Accessing the Tar file
The following example extracts the contents of a tar file:
Package Mainimport ("IO" "OS" "FMT" "Path" "Encoding/json" "Archive/tar") Func extract (Tarfile string) { Reader, err: = OS. Open (tarfile) if err! = Nil {fmt. Printf ("Error:cannot read tar file, error=[%v]\n", err) return} defer reader. Close () Tarreader: = Tar. Newreader (reader) for {header, err: = Tarreader.next () If err = = Io. EOF {Break} else if err! = Nil {fmt. Printf ("Error:cannot read tar file, error=[%v]\n", err) return} j, err: = json. Marshal (header) If err! = Nil {fmt. Printf ("Error:cannot parse header, error=[%v]\n", err) return} FMT. Printf ("header=%s\n", String (j)) Info: = header. FileInfo () if info. Isdir () {If err = os. Mkdirall (header. Name, 0755); Err! = Nil {fmt. Printf ("Error:cannot mkdir file, error=[%v]\n", err) return}} else { If Err = OS. Mkdirall (path. Dir (header. Name), 0755); Err! = Nil {fmt. Printf ("Error:cannot file mkdir file, error=[%v]\n", err) return} file, err:= os. OpenFile (header. Name, OS. O_create|os. O_trunc|os. O_wronly, Info. Mode ()) if err! = Nil {fmt. Printf ("Error:cannot Open file, error=[%v]\n", err) return} defer file. Close () _, Err =io. Copy (file, tarreader) if err! = Nil {fmt. Printf ("Error:cannot write file, error=[%v]\n", err) return}}}
The format definition of the tar file:
Https://www.gnu.org/software/tar/manual/html_node/Standard.html
Each file contains a 512-byte header and then the file content, so the tar file generated for the small file is much larger than the original file. Each of the original files into tar contains at least 1024 bytes (512 of the header information, then the file content, less than 512 bytes after the 0); So if the original file size is a byte size, the resulting tar file will have a 1024-byte size, The conclusion is that small files should not use tar.gz compressed storage.
With tar it's natural to think of GZ, because tar.gz.
The following template example is used to handle tar.gz read and write:
Read the contents of the tar.gz file:
body := bytes.NewReader([]byte{...}) gr, err := gzip.NewReader(body) tr := tar.NewReader(gr) for { header, err := tr.Next() if err != nil { // We only get here if there are no more entries to scan break } HANLD_AN_ENTRY }
Generate the tar.gz file:
Payload: = bytes. Newbuffer (nil) GW: = gzip. Newwriter (payload) TW: = tar. Newwriter (GW) for _, File: = Range Files {info, err: = OS. Stat (file) header, err: = Tar. Fileinfoheader (info, file) Err = tw. Writeheader (header); FD, ERR: = OS. Open (file) _, Err: = Io. Copy (TW, Bufio. Newreader (FD)); } tw. Close () GW. Close () write payload. Bytes () into file.