使用Golang IO.Pipe进行焦油文件的错误



我一直在使用io.pipe来测试代码,以将焦油和gunzip文件放入焦油球,然后使用焦油实用程序解压缩。后面的代码通过,但是不介意的过程不断获得

错误: tar: Truncated input file (needed 1050624 bytes, only 0 available) tar: Error exit delayed from previous errors.

这个问题确实使我发疯。已经两个星期了。我真的需要帮助调试。

谢谢。

开发环境:GO版本GO1.9 Darwin/AMD64

package main
import (
    "archive/tar"
    "compress/gzip"
    "fmt"
    "io"
    "log"
    "os"
    "path/filepath"
    "testing"
)
func testTarGzipPipe2(t *testing.T) {
    src := "/path/to/file/folder"
    pr, pw := io.Pipe()
    gzipWriter := gzip.NewWriter(pw)
    defer gzipWriter.Close()
    tarWriter := tar.NewWriter(gzipWriter)
    defer tarWriter.Close()
    status := make(chan bool)
    go func() {
        defer pr.Close()
        // tar to local disk
        tarFile, err := os.OpenFile("/path/to/tar/ball/test.tar.gz", os.O_RDWR|os.O_CREATE, 0755)
        if err != nil {
            log.Fatal(err)
        }
        defer tarFile.Close()
        if _, err := io.Copy(tarFile, pr); err != nil {
            log.Fatal(err)
        }
        status <- true
    }()
    err := filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        header, err := tar.FileInfoHeader(info, info.Name())
        if err != nil {
            return err
        }
        // header.Name = strings.TrimPrefix(strings.Replace(path, src, "", -1), string(filepath.Separator))
        if err := tarWriter.WriteHeader(header); err != nil {
            return err
        }
        if info.Mode().IsDir() {
            return nil
        }
        fmt.Println(path)
        f, err := os.Open(path)
        if err != nil {
            return err
        }
        defer f.Close()
        if _, err := io.Copy(tarWriter, f); err != nil {
            return err
        }
        return nil
    })
    if err != nil {
        log.Fatal(err)
    }
    pw.Close()
    <-status
}

您要在gzipWritertarWriter上的递延关闭呼叫之前关闭管道。没有错误,因为您没有检查任何一个关闭呼叫中的任何一个错误。您需要按照该顺序关闭tarWriter,然后关闭gzipWriter,然后关闭PipeWriter

但是,本代码中根本没有管道的理由,如果直接写入文件,您可以完全删除Goroutine和相关的协调。

tarFile, err := os.OpenFile("/tmp/test.tar.gz", os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
    log.Fatal(err)
}
defer tarFile.Close()
gzipWriter := gzip.NewWriter(tarFile)
defer gzipWriter.Close()
tarWriter := tar.NewWriter(gzipWriter)
defer tarWriter.Close()

相关内容

  • 没有找到相关文章

最新更新