解压缩具有不同名称的工件 [英] Unzip artifacts with different name
问题描述
我有一个程序需要将文件夹内容(从 folder1
)复制到一个新文件夹( folder2
)在相同的目录级别(路径)。
因为我不能使用相同的名称,所以我使用tmpFolder名称(用于 folder2
)。
当我完成所有我需要的逻辑时,将复制的文件夹
压缩,然后给zip命名 folder1.zip
问题是,当我提取 folder1.zip
时,我看到 folder2
。
我希望它在zip之后是 folder1
。
有没有我可以用它来做这件事吗?另外,我知道我可以复制到不同级别的文件夹(路径),但我想避免它,如果可能的话,因为
的副本可以是非常当使用大文件夹内容时,价格昂贵。
我使用以下代码压缩文件夹:
func Zipit(source,target string)错误{
zipfile,err:= os.Create(target)
if err!= nil {
return err
}
推迟zipfile.Close()
存档:= zip.NewWriter(zipfile)
推迟archive.Close()
info,err := os.Stat(source)
if err!= nil {
return nil
}
var baseDir string
if info.IsDir() {
baseDir = filepath.Base(source)
}
filepath.Walk(source,func(path string,info os.FileInfo,err error)error {
如果err!= nil {
return err
}
header,err:= zip.FileInfoHeader(info)
i f err!= nil {
return err
}
if baseDir!={
header.Name = filepath.Join(baseDir,strings.TrimPrefix(来源))
}
if info.IsDir(){
header.Name + =/
} else {
header。 Method = zip.Deflate
}
writer,err:= archive.CreateHeader(header)
if err!= nil {
return err
}
if info.IsDir(){
return nil
}
file,err:= os.Open(path)
if err!= nil {
return err
}
推迟file.Close()
_,err = io.Copy(writer,file)
return err
$)
return err
}
zip档案中的文件和目录名称来自 zip.FileHeader 。
您的代码已经从 os.FileInfo 。这一点很重要,因为它填充了时间戳和未压缩大小等元数据。
此外,您的代码似乎在执行以下操作:
如果使用:
Zipit(/ path / to / folder2 /,/ path / to /folder1.zip)
在遍历目录树之前,它会计算基本目录:
baseDir = filepath.Base(源)
// baseDir是folder2
然后对于每个文件,存档中的路径设置为:
header.Name = filepath.Join(baseDir,strings.TrimPrefix(path,source))
这会将文件名(如
/ path / to / folder2 / otherdir / myfile
)转换为folder2 / otherdir / myfile
如果您想更改存档内存储的目录名称,只需更改
baseDir
到所需的名称。
我会推荐以下解决方案:
更改函数签名为:
func Zipit (source,target,newBaseName string)error {
更改basedir为:
if newBaseName!={
baseDir = newBaseName
else if info.IsDir(){
baseDir = filepath.Base(source)
}
然后调用你的函数:
$ b $Zipit(/ path / to / folder2 /,/path/to/folder1.zip,folder1)
这会导致归档文件解压到
folder1 /
。I have a program in which I need to copy the folder contents (from
folder1
) to a new folder (folder2
) in the same dir level (path). Since I cannot give the same name I use tmpFolder name (forfolder2
). When I finish to do all the logic I need zip the copied folder and I give the zip the namefolder1.zip
The problem is that when I extract thefolder1.zip
I seefolder2
.I want it to be
folder1
after the zip.Is there some trick I can use to do it?
In addition, I know that I can copy to folder2 in different level (path) but I want to avoid it if possible since the copy can be very expensive when working on big folder contents.
I use this code to zip the folder:
func Zipit(source, target string) error { zipfile, err := os.Create(target) if err != nil { return err } defer zipfile.Close() archive := zip.NewWriter(zipfile) defer archive.Close() info, err := os.Stat(source) if err != nil { return nil } var baseDir string if info.IsDir() { baseDir = filepath.Base(source) } filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if err != nil { return err } header, err := zip.FileInfoHeader(info) if err != nil { return err } if baseDir != "" { header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source)) } if info.IsDir() { header.Name += "/" } else { header.Method = zip.Deflate } writer, err := archive.CreateHeader(header) if err != nil { return err } if info.IsDir() { return nil } file, err := os.Open(path) if err != nil { return err } defer file.Close() _, err = io.Copy(writer, file) return err }) return err }
解决方案Names of files and directories in zip archives come from the zip.FileHeader.
Your code already initializes the header from the os.FileInfo. This is important as it populates metadata such as timestamps and uncompressed size.
Furthermore, your code seems to be doing the following:
If invoked with:
Zipit("/path/to/folder2/", "/path/to/folder1.zip")
Before traversing the directory tree, it computes the base directory:
baseDir = filepath.Base(source) // baseDir is "folder2"
Then for each file, the path inside the archive is set to:
header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
This turns a filename such as
/path/to/folder2/otherdir/myfile
intofolder2/otherdir/myfile
.If you want to change the directory name stored inside the archive, you just need to change
baseDir
to the desired name.I would recommend the following solution:
Change the function signature to:
func Zipit(source, target, newBaseName string) error {
Change the basedir to:
if newBaseName != "" { baseDir = newBaseName else if info.IsDir() { baseDir = filepath.Base(source) }
Then call your function with:
Zipit("/path/to/folder2/", "/path/to/folder1.zip", "folder1")
This should result in an archive that extracts into
folder1/
.这篇关于解压缩具有不同名称的工件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!