在Go中解压tarball文件。

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

Unpack a tarball in Go

问题

我正在为您翻译以下内容:

我正在编写一个程序的一部分,其中包含一个函数,用于解压tar文件并返回其内容的列表。

除了提取的文件为空之外,一切似乎都正常工作。我可以将文件内容提取到标准输出并查看它确实给出了正确的内容,只是不确定为什么它没有写入文件。

函数如下:

func UnpackTarball(filename, extractpath string) ([]string, error) {
    buf, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }

    if err = os.MkdirAll(extractpath, os.ModeDir|0755); err != nil {
        return nil, err
    }

    tarball := tar.NewReader(bytes.NewReader(buf))
    contentlist := make([]string, 0, 500)

    // 遍历存档中的文件
    for {
        hdr, err := tarball.Next()
        if err == io.EOF {
            // tar存档结束
            break
        }
        if err != nil {
            return nil, err
        }

        info := hdr.FileInfo()
        entry := path.Join(extractpath, hdr.Name)

        // entry是否为目录?
        if info.IsDir() {
            if err = os.MkdirAll(entry, os.ModeDir|0755); err != nil {
                return nil, err
            }
            continue
        }

        // 将entry添加到内容列表
        contentlist = append(contentlist, hdr.Name)
        // 创建文件
        f, err := os.Create(entry)
        if err != nil {
            return nil, err
        }
        defer f.Close()

        _, err = io.Copy(bufio.NewWriter(f), tarball)
        //_, err = io.Copy(os.Stdout, tarball)
        if err != nil {
            return nil, err
        }
    }
    return contentlist, nil
}

感谢您的帮助。

英文:

For part of a program I'm writing I have a function for unpacking a tarball and returning a list of its content.

Everything appears to work except the extracted files are empty. I can extract the files content to stdout and see that it does give the correct content, just not sure why its not writing to the files.

The function:

func UnpackTarball(filename, extractpath string) ([]string, error) {
buf, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
if err = os.MkdirAll(extractpath, os.ModeDir|0755); err != nil {
return nil, err
}
tarball := tar.NewReader(bytes.NewReader(buf))
contentlist := make([]string, 0, 500)
// Iterate through the files in the archive
for {
hdr, err := tarball.Next()
if err == io.EOF {
// end of tar archive
break
}
if err != nil {
return nil, err
}
info := hdr.FileInfo()
entry := path.Join(extractpath, hdr.Name)
// Is entry a directory?
if info.IsDir() {
if err = os.MkdirAll(entry, os.ModeDir|0755); err != nil {
return nil, err
}
continue
}
// Append entry to the content list
contentlist = append(contentlist, hdr.Name)
// Create file
f, err := os.Create(entry)
if err != nil {
return nil, err
}
defer f.Close()
_, err = io.Copy(bufio.NewWriter(f), tarball)
//_, err = io.Copy(os.Stdout, tarball)
if err != nil {
return nil, err
}
}
return contentlist, nil
}

Thanks for any help.

答案1

得分: 3

你没有清空缓冲写入器的内容,因此如果文件足够小,你将不会写入任何内容。在io.Copy()调用之后的某个地方调用bufio.(*Writer).Flush()

此外,你可能希望在循环中关闭输出文件,而不是在所有文件都被写入之后再延迟关闭。

英文:

You are not flushing the contents of the buffered writer and consequently you are not writing anything if the files are small enough. Place a call to bufio.(*Writer).Flush() somewhere after your io.Copy() call.

Also, you might want to close the output files in the loop instead of deferring until all files have been written.

huangapple
  • 本文由 发表于 2014年11月2日 02:12:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/26691458.html
匿名

发表评论

匿名网友

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

确定