1
0
Fork 0
golang-github-mholt-archiver/doc_test.go
Daniel Baumann 097626e61a
Adding upstream version 3.5.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-18 18:07:37 +02:00

260 lines
7.2 KiB
Go

package archiver
import (
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
)
// The simplest use of this package: create an archive file
// from a list of filenames. This is the recommended way to
// do so using a default configuration, as it guarantees
// the file format matches the file extension, because the
// format to write is determined by the given extension.
func ExampleArchive() {
// any files in this list are added
// to the top level of the archive;
// directories are recursively added
files := []string{
"index.html",
"photo.jpg",
"blog", // directory
"/home/website/copyright.txt",
}
// archive format is determined by file extension
err := Archive(files, "blog_site.zip")
if err != nil {
log.Fatal(err)
}
}
// The simplest use of this package: extract all of an archive's
// contents to a folder on disk using the default configuration.
// The archive format is determined automatically.
func ExampleUnarchive() {
err := Unarchive("blog_site.zip", "extracted/mysite")
if err != nil {
log.Fatal(err)
}
}
// In this example, the DefaultZip is being customized so that
// all calls to its methods will use that configuration.
func ExampleZip_default() {
DefaultZip.OverwriteExisting = true
DefaultZip.ImplicitTopLevelFolder = true
// any subsequent use of DefaultZip uses
// this modified configuration
}
// Here we create our own instance of the Zip format. No need
// to use the constructor function (NewZip) or the default
// instance (DefaultZip) if we do not want to. Instantiating
// the type like this allows us to easily be very explicit
// about our configuration.
func ExampleZip_custom() {
z := &Zip{
CompressionLevel: 3,
OverwriteExisting: false,
MkdirAll: true,
SelectiveCompression: true,
ImplicitTopLevelFolder: true,
ContinueOnError: false,
}
// z is now ready to use for whatever (this is a dumb example)
fmt.Println(z.CheckExt("test.zip"))
}
// Much like the package-level Archive function, this creates an
// archive using the configuration of the Zip instance it is called
// on. The output filename must match the format's recognized file
// extension(s).
func ExampleZip_Archive() {
err := DefaultZip.Archive([]string{"..."}, "example.zip")
if err != nil {
log.Fatal(err)
}
}
// It's easy to list the items in an archive. This example
// prints the name and size of each file in the archive. Like
// other top-level functions in this package, the format is
// inferred automatically for you.
func ExampleWalk() {
err := Walk("example.tar.gz", func(f File) error {
fmt.Println(f.Name(), f.Size())
// you could also read the contents; f is an io.Reader!
return nil
})
if err != nil {
log.Fatal(err)
}
}
// This example extracts target.txt from inside example.rar
// and puts it into a folder on disk called output/dir.
func ExampleExtract() {
err := Extract("example.rar", "target.txt", "output/dir")
if err != nil {
log.Fatal(err)
}
}
// This example demonstrates how to read an
// archive in a streaming fashion. The idea
// is that you can stream the bytes of an
// archive from a stream, regardless of
// whether it is an actual file on disk.
// This means that you can read a huge
// archive file-by-file rather than having
// to store it all on disk first. In this
// example, we read a hypothetical archive
// from a (fake) HTTP request body and
// print its file names and sizes. The
// files can be read, of course, but they
// do not have to be.
func ExampleZip_streamingRead() {
// for the sake of the example compiling, pretend we have an HTTP request
req := new(http.Request)
contentLen, err := strconv.Atoi(req.Header.Get("Content-Length"))
if err != nil {
log.Fatal(err)
}
// the Zip format requires knowing the length of the stream,
// but other formats don't generally require it, so it
// could be left as 0 when using those
err = DefaultZip.Open(req.Body, int64(contentLen))
if err != nil {
log.Fatal(err)
}
defer DefaultZip.Close()
// Note that DefaultZip now contains some state that
// is critical to reading the stream until it is closed,
// so do not reuse it until then.
// iterate each file in the archive until EOF
for {
f, err := DefaultZip.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
// f is an io.ReadCloser, so you can read its contents
// if you wish; or you can access its header info through
// f.Header or the embedded os.FileInfo
fmt.Println("File name:", f.Name(), "File size:", f.Size())
// be sure to close f before moving on!!
err = f.Close()
if err != nil {
log.Fatal(err)
}
}
}
// This example demonstrates how to write an
// archive in a streaming fashion. The idea
// is that you can stream the bytes of a new
// archive that is created on-the-fly from
// generic streams. Those streams could be
// actual files on disk, or they could be over
// a network, or standard output, or any other
// io.Reader/io.Writer. This example only adds
// one file to the archive and writes the
// resulting archive to standard output, but you
// could add as many files as needed with a loop.
func ExampleZip_streamingWrite() {
err := DefaultZip.Create(os.Stdout)
if err != nil {
log.Fatal(err)
}
defer DefaultZip.Close()
// Note that DefaultZip now contains state
// critical to a successful write until it
// is closed, so don't reuse it for anything
// else until then.
// At this point, you can open an actual file
// to add to the archive, or the "file" could
// come from any io.ReadCloser stream. If you
// only have an io.Reader, you can use
// ReadFakeCloser to make it into an
// io.ReadCloser.
// The next part is a little tricky if you
// don't have an actual file because you will
// need an os.FileInfo. Fortunately, that's an
// interface! So go ahead and implement it in
// whatever way makes the most sense to you.
// You'll also need to give the file a name
// for within the archive. In this example,
// we'll open a real file.
file, err := os.Open("foo.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
log.Fatal(err)
}
err = DefaultZip.Write(File{
FileInfo: FileInfo{
FileInfo: fileInfo,
CustomName: "name/in/archive.txt",
},
ReadCloser: file, // does not have to be an actual file
})
if err != nil {
log.Fatal(err)
}
}
// This example compresses a standard tar file into a tar.gz file.
// Compression formats are selected by file extension.
func ExampleCompressFile() {
err := CompressFile("example.tar", "example.tar.gz")
if err != nil {
log.Fatal(err)
}
}
// This example changes the default configuration for
// the Gz compression format.
func ExampleCompressFile_custom() {
DefaultGz.CompressionLevel = 5
// any calls to DefaultGz now use the modified configuration
}
// This example creates a new Gz instance and
// uses it to compress a stream, writing to
// another stream. This is sometimes preferable
// over modifying the DefaultGz.
func ExampleGz_Compress_custom() {
gz := &Gz{CompressionLevel: 5}
err := gz.Compress(os.Stdin, os.Stdout)
if err != nil {
log.Fatal(err)
}
}
// This example decompresses a gzipped tarball and writes
// it to an adjacent file.
func ExampleDecompressFile() {
err := DecompressFile("example.tar.gz", "example.tar")
if err != nil {
log.Fatal(err)
}
}