github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/src/archive/tar/example_test.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tar_test
     6  
     7  import (
     8  	"archive/tar"
     9  	"bytes"
    10  	"crypto/md5"
    11  	"fmt"
    12  	"io"
    13  	"io/ioutil"
    14  	"log"
    15  	"os"
    16  	"strings"
    17  )
    18  
    19  func Example() {
    20  	buf := new(bytes.Buffer)
    21  
    22  	// Create and add some files to the archive.
    23  	tw := tar.NewWriter(buf)
    24  	var files = []struct {
    25  		Name, Body string
    26  	}{
    27  		{"readme.txt", "This archive contains some text files."},
    28  		{"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
    29  		{"todo.txt", "Get animal handling license."},
    30  	}
    31  	for _, file := range files {
    32  		hdr := &tar.Header{
    33  			Name: file.Name,
    34  			Mode: 0600,
    35  			Size: int64(len(file.Body)),
    36  		}
    37  		if err := tw.WriteHeader(hdr); err != nil {
    38  			log.Fatal(err)
    39  		}
    40  		if _, err := tw.Write([]byte(file.Body)); err != nil {
    41  			log.Fatal(err)
    42  		}
    43  	}
    44  	if err := tw.Close(); err != nil {
    45  		log.Fatal(err)
    46  	}
    47  
    48  	// Open and iterate through the files in the archive.
    49  	tr := tar.NewReader(buf)
    50  	for {
    51  		hdr, err := tr.Next()
    52  		if err == io.EOF {
    53  			break // End of archive
    54  		}
    55  		if err != nil {
    56  			log.Fatal(err)
    57  		}
    58  		fmt.Printf("Contents of %s:\n", hdr.Name)
    59  		if _, err := io.Copy(os.Stdout, tr); err != nil {
    60  			log.Fatal(err)
    61  		}
    62  		fmt.Println()
    63  	}
    64  
    65  	// Output:
    66  	// Contents of readme.txt:
    67  	// This archive contains some text files.
    68  	// Contents of gopher.txt:
    69  	// Gopher names:
    70  	// George
    71  	// Geoffrey
    72  	// Gonzo
    73  	// Contents of todo.txt:
    74  	// Get animal handling license.
    75  }
    76  
    77  // A sparse file can efficiently represent a large file that is mostly empty.
    78  func Example_sparse() {
    79  	buf := new(bytes.Buffer)
    80  
    81  	// Define a sparse file to add to the archive.
    82  	// This sparse files contains 5 data fragments, and 4 hole fragments.
    83  	// The logical size of the file is 16 KiB, while the physical size of the
    84  	// file is only 3 KiB (not counting the header data).
    85  	hdr := &tar.Header{
    86  		Name: "sparse.db",
    87  		Size: 16384,
    88  		SparseHoles: []tar.SparseEntry{
    89  			// Data fragment at 0..1023
    90  			{Offset: 1024, Length: 1024 - 512}, // Hole fragment at 1024..1535
    91  			// Data fragment at 1536..2047
    92  			{Offset: 2048, Length: 2048 - 512}, // Hole fragment at 2048..3583
    93  			// Data fragment at 3584..4095
    94  			{Offset: 4096, Length: 4096 - 512}, // Hole fragment at 4096..7679
    95  			// Data fragment at 7680..8191
    96  			{Offset: 8192, Length: 8192 - 512}, // Hole fragment at 8192..15871
    97  			// Data fragment at 15872..16383
    98  		},
    99  	}
   100  
   101  	// The regions marked as a sparse hole are filled with NUL-bytes.
   102  	// The total length of the body content must match the specified Size field.
   103  	body := "" +
   104  		strings.Repeat("A", 1024) +
   105  		strings.Repeat("\x00", 1024-512) +
   106  		strings.Repeat("B", 512) +
   107  		strings.Repeat("\x00", 2048-512) +
   108  		strings.Repeat("C", 512) +
   109  		strings.Repeat("\x00", 4096-512) +
   110  		strings.Repeat("D", 512) +
   111  		strings.Repeat("\x00", 8192-512) +
   112  		strings.Repeat("E", 512)
   113  
   114  	h := md5.Sum([]byte(body))
   115  	fmt.Printf("Write content of %s, Size: %d, MD5: %08x\n", hdr.Name, len(body), h)
   116  	fmt.Printf("Write SparseHoles of %s:\n\t%v\n\n", hdr.Name, hdr.SparseHoles)
   117  
   118  	// Create a new archive and write the sparse file.
   119  	tw := tar.NewWriter(buf)
   120  	if err := tw.WriteHeader(hdr); err != nil {
   121  		log.Fatal(err)
   122  	}
   123  	if _, err := tw.Write([]byte(body)); err != nil {
   124  		log.Fatal(err)
   125  	}
   126  	if err := tw.Close(); err != nil {
   127  		log.Fatal(err)
   128  	}
   129  
   130  	// Open and iterate through the files in the archive.
   131  	tr := tar.NewReader(buf)
   132  	for {
   133  		hdr, err := tr.Next()
   134  		if err == io.EOF {
   135  			break
   136  		}
   137  		if err != nil {
   138  			log.Fatal(err)
   139  		}
   140  		body, err := ioutil.ReadAll(tr)
   141  		if err != nil {
   142  			log.Fatal(err)
   143  		}
   144  
   145  		h := md5.Sum([]byte(body))
   146  		fmt.Printf("Read content of %s, Size: %d, MD5: %08x\n", hdr.Name, len(body), h)
   147  		fmt.Printf("Read SparseHoles of %s:\n\t%v\n\n", hdr.Name, hdr.SparseHoles)
   148  	}
   149  
   150  	// Output:
   151  	// Write content of sparse.db, Size: 16384, MD5: 9b4e2cfae0f9303d30237718e891e9f9
   152  	// Write SparseHoles of sparse.db:
   153  	// 	[{1024 512} {2048 1536} {4096 3584} {8192 7680}]
   154  	//
   155  	// Read content of sparse.db, Size: 16384, MD5: 9b4e2cfae0f9303d30237718e891e9f9
   156  	// Read SparseHoles of sparse.db:
   157  	// 	[{1024 512} {2048 1536} {4096 3584} {8192 7680} {16384 0}]
   158  }