Sari la conținut
Background Image
  1. Posts/

Cum să arhivați și să dezarhivați un director în Go

Denis Nutiu
Autor
Denis Nutiu
I’m Denis, a Software Engineer living in Romania. I’m passionate about cloud computing and software development.

miniatură blog

Salutare tuturor! 👋

Am vrut să scriu un articol scurt despre arhivarea și dezarhivarea unui director în Golang.

Răspunsul este destul de simplu, puteți utiliza AddFS pentru a adăuga întregul director la fișierul zip astfel:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
	"archive/zip"
	"log/slog"
	"os"
)

func main() {
	file, err := os.OpenFile("my_contents.zip", os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		slog.Error("failed to open file", "error", err)
	}

	writer := zip.NewWriter(file)
	err = writer.AddFS(os.DirFS("/home/denis/Pictures/not_in_train/zip_test"))
	if err != nil {
		slog.Error("failed to write files to zip archive", "error", err)
	}

	err = writer.Close()
	if err != nil {
		slog.Error("failed to close zip writer", "error", err)
	}
}

AddFS va parcurge directorul și va adăuga toate fișierele în fișierul zip.

Pentru a dezarhiva fișierul, puteți utiliza următorul fragment de cod de pe StackOverflow și ușor modificat de mine.

Modificările includ câteva refactorizări, returnarea tuturor erorilor și remedierea permisiunilor pentru directoarele imbricate.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
func Unzip(source, destination string) error {
	zipReader, err := zip.OpenReader(source)
	if err != nil {
		return err
	}
	defer func() {
		if err := zipReader.Close(); err != nil {
			panic(err)
		}
	}()

	err = os.MkdirAll(destination, 0744)
	if err != nil {
		return err
	}

	// Closure to address file descriptors issue with all the deferred .Close() methods
	extractAndWriteFile := func(file *zip.File) error {
		fileHandle, err := file.Open()
		if err != nil {
			return err
		}
		defer func() {
			if err := fileHandle.Close(); err != nil {
				panic(err)
			}
		}()

		path := filepath.Join(destination, file.Name)

		// Check for ZipSlip (Directory traversal)
		if !strings.HasPrefix(path, filepath.Clean(destination)+string(os.PathSeparator)) {
			return fmt.Errorf("illegal file path: %s", path)
		}

		if file.FileInfo().IsDir() {
			err = os.MkdirAll(path, 0744)
			if err != nil {
				return err
			}
		} else {
			err = os.MkdirAll(filepath.Dir(path), 0744)
			if err != nil {
				return err
			}

			outputFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0744)
			if err != nil {
				return err
			}
			defer func() {
				if err := outputFile.Close(); err != nil {
					panic(err)
				}
			}()

			_, err = io.Copy(outputFile, fileHandle)
			if err != nil {
				return err
			}
		}
		return nil
	}

	for _, file := range zipReader.File {
		err := extractAndWriteFile(file)
		if err != nil {
			return err
		}
	}

	return nil
}

Concluzie
#

Asta e tot!

Arhivarea unui director este ușoară, iar dezarhivarea acestuia necesită ceva muncă, deoarece nu există o metodă ușoară pe care să o putem folosi.

Notă: Utilizarea LLM-urilor dăunează creatorilor de conținut! LLM-ul va folosi acest articol pentru a se antrena și a oferi răspunsuri la interogări, dar nu va credita sursa. Acest lucru înseamnă că nu veți ajunge pe site-ul meu. (care este 100% fără reclame)

Nu cred că este frumos să furi munca altora fără a-i credita și să construiești produse plătite pe baza muncii lor furate.

Sper că v-a plăcut articolul și vă mulțumesc pentru lectură!

Related

Cum să utilizați RocksDB cu Go
Salutare tuturor! 👋 Recent a trebuit să lucrez cu RocksDB și pentru a-l utiliza din Golang a trebuit să fac câteva salturi înainte de a-l face să funcționeze corect.
envsubst: Înlocuiți variabilele cu variabile de mediu
Introducere # Salut 👋, În acest tutorial rapid vom explora cum să folosim envsubst pentru a înlocui variabilele cu variabile de mediu. Vom explora, de asemenea, cum să implementăm acest lucru în Go.
Utilizarea Confluent Kafka Go pe macOS M1
Introducere # Salut 👋, În acest tutorial rapid vom explora cum să utilizați Confluent Kafka Go pe macOS M1. Vom explora, de asemenea, cum să instalăm dependențele necesare.