代码之家  ›  专栏  ›  技术社区  ›  NSTNF

使用golang io的错误。管道到tar文件

  •  0
  • NSTNF  · 技术社区  · 8 年前

    我一直在使用io测试代码。通过管道将tar和gunzip文件传输到tar球中,然后使用tar实用程序解压。下面的代码通过了,但是解构过程一直在进行

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

    这个问题真的快把我逼疯了。已经两周了。我真的需要帮助调试。

    谢谢

    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
    }
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   JimB    8 年前

    在上的延迟关闭调用之前,您正在关闭管道 gzipWriter tarWriter ,然后 GZIP编写器 ,然后 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()