Golang – 压缩一个包含空子目录和文件的目录

huangapple go评论75阅读模式
英文:

Golang - Zip a directory which includes empty subdirectory and files

问题

我正在尝试压缩一个已存在的目录,其中包含一些空的子目录。

以下是文件夹结构:

parent/
├── child
│    └── child.txt
├── empty-folder
└── parent.txt

2个目录,2个文件

以下是源代码。它将所有包含文件的子目录写入压缩文件,但跳过了空的子目录。有没有办法也将空的子目录添加到压缩文件中?提前谢谢。

package main

import (
	"archive/zip"
	"fmt"
	"io"
	"os"
	"path/filepath"
)

// 检查错误并停止执行
func checkForError(err error) {
	if err != nil {
		fmt.Println("错误 - ", err)
		os.Exit(1)
	}
}

const (
	ZIP_FILE_NAME    = "example.zip"
	MAIN_FOLDER_NAME = "parent"
)

// 主函数
func main() {

	var targetFilePaths []string

	// 获取所有文件夹中的文件路径
	err := filepath.Walk(MAIN_FOLDER_NAME, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		// 将所有文件路径添加到切片中
		targetFilePaths = append(targetFilePaths, path)
		return nil
	})
	checkForError(err)

	// 压缩文件逻辑从这里开始
	ZipFile, err := os.Create(ZIP_FILE_NAME)
	checkForError(err)
	defer ZipFile.Close()

	zipWriter := zip.NewWriter(ZipFile)
	defer zipWriter.Close()

	for _, targetFilePath := range targetFilePaths {

		file, err := os.Open(targetFilePath)
		checkForError(err)
		defer file.Close()

		// 在压缩文件中创建路径
		w, err := zipWriter.Create(targetFilePath)
		checkForError(err)

		// 将文件写入压缩文件
		_, err = io.Copy(w, file)
		checkForError(err)

	}

}
英文:

I am trying to zip an existing directory that has some empty subdirectories as well.

Here is the folder structure.

parent/
├── child
│   └── child.txt
├── empty-folder
└── parent.txt
2 directories, 2 files

Here is the source code. It writes all the subdirectories which have files on that. But it skipped an empty subdirectory. Is there any way to add an empty subdirectory as well in the zip file?. Thanks in advance.

package main
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
)
// check for error and stop the execution
func checkForError(err error) {
if err != nil {
fmt.Println("Error - ", err)
os.Exit(1)
}
}
const (
ZIP_FILE_NAME    = "example.zip"
MAIN_FOLDER_NAME = "parent"
)
// Main function
func main() {
var targetFilePaths []string
// get filepaths in all folders
err := filepath.Walk(MAIN_FOLDER_NAME, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
// add all the file paths to slice
targetFilePaths = append(targetFilePaths, path)
return nil
})
checkForError(err)
// zip file logic starts here
ZipFile, err := os.Create(ZIP_FILE_NAME)
checkForError(err)
defer ZipFile.Close()
zipWriter := zip.NewWriter(ZipFile)
defer zipWriter.Close()
for _, targetFilePath := range targetFilePaths {
file, err := os.Open(targetFilePath)
checkForError(err)
defer file.Close()
// create path in zip
w, err := zipWriter.Create(targetFilePath)
checkForError(err)
// write file to zip
_, err = io.Copy(w, file)
checkForError(err)
}
}

答案1

得分: 0

要写入一个空目录,只需使用带有目录路径和尾部路径分隔符的 Create 函数。

package main

import (
	"archive/zip"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
)

const (
	ZIP_FILE_NAME    = "example.zip"
	MAIN_FOLDER_NAME = "parent"
)

type fileMeta struct {
	Path  string
	IsDir bool
}

func main() {
	var files []fileMeta
	err := filepath.Walk(MAIN_FOLDER_NAME, func(path string, info os.FileInfo, err error) error {
		files = append(files, fileMeta{Path: path, IsDir: info.IsDir()})
		return nil
	})
	if err != nil {
		log.Fatalln(err)
	}

	z, err := os.Create(ZIP_FILE_NAME)
	if err != nil {
		log.Fatalln(err)
	}
	defer z.Close()

	zw := zip.NewWriter(z)
	defer zw.Close()

	for _, f := range files {
		path := f.Path
		if f.IsDir {
			path = fmt.Sprintf("%s%c", path, os.PathSeparator)
		}

		w, err := zw.Create(path)
		if err != nil {
			log.Fatalln(err)
		}

		if !f.IsDir {
			file, err := os.Open(f.Path)
			if err != nil {
				log.Fatalln(err)
			}
			defer file.Close()

			if _, err = io.Copy(w, file); err != nil {
				log.Fatalln(err)
			}
		}
	}
}
英文:

To write an empty directory you just need to call Create with the directory path with a trailing path separator.

package main
import (
"archive/zip"
"fmt"
"io"
"log"
"os"
"path/filepath"
)
const (
ZIP_FILE_NAME    = "example.zip"
MAIN_FOLDER_NAME = "parent"
)
type fileMeta struct {
Path  string
IsDir bool
}
func main() {
var files []fileMeta
err := filepath.Walk(MAIN_FOLDER_NAME, func(path string, info os.FileInfo, err error) error {
files = append(files, fileMeta{Path: path, IsDir: info.IsDir()})
return nil
})
if err != nil {
log.Fatalln(err)
}
z, err := os.Create(ZIP_FILE_NAME)
if err != nil {
log.Fatalln(err)
}
defer z.Close()
zw := zip.NewWriter(z)
defer zw.Close()
for _, f := range files {
path := f.Path
if f.IsDir {
path = fmt.Sprintf("%s%c", path, os.PathSeparator)
}
w, err := zw.Create(path)
if err != nil {
log.Fatalln(err)
}
if !f.IsDir {
file, err := os.Open(f.Path)
if err != nil {
log.Fatalln(err)
}
defer file.Close()
if _, err = io.Copy(w, file); err != nil {
log.Fatalln(err)
}
}
}
}

huangapple
  • 本文由 发表于 2021年12月24日 09:36:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/70468850.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定