将提取的tar.gz文件复制到单个文件中。

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

Copying extracted tar.gz to a single file

问题

我正在尝试将tar.gz文件中提取的内容复制到一个单独的文件中,使用的是Go语言。文件中只包含文本。

以下是我的当前代码:

f, err := os.Open(fullpath)
if err != nil {
    log.Panicf("无法打开文件 %s:%v", fullpath, err)
    return ""
}
defer f.Close()
reader, err := gzip.NewReader(f)
if err != nil{
    log.Panicf("无法读取gzip归档文件 %v", err)
    return ""
}
defer reader.Close()
tar_reader := tar.NewReader(reader)
var files []io.Reader
for {
    header, err := tar_reader.Next()
    if err == io.EOF {
        break
    } else if err != nil {
        log.Panicf("无法读取tarball中的文件 %v", err)
        return 0, err
    } else {
        log.Println("解析文件:", header.Name)
        files = append(files, tar_reader)
    }
}
reader = io.MultiReader(files...)
writer, err := os.Create(target)
if err != nil {
    log.Panicf("无法写入未归档文件 %v", err)
    return 0, err
}
defer writer.Close()

result, err := io.Copy(writer, reader)
if err != nil {
    log.Panicf("无法写入未归档文件 %v", err)
}
return result, err

虽然上述代码没有报错,但文件并没有被读取。输出中没有数据。请指出我哪里出错了。

英文:

I am trying to copy the extracted content of a tar.gz to a single file in go lang. I will have only text inside the files.

The following is my current code.

f, err := os.Open(fullpath)
if err != nil {
    log.Panicf("Can not open file %s: %v", fullpath, err)
    return ""
}
defer f.Close()
reader, err := gzip.NewReader(f)
if err != nil{
    log.Panicf("Cannot read gzip archive %v", err);
    return ""
}
defer reader.Close()
tar_reader := tar.NewReader(reader)
var files []io.Reader
for{
    header, err := tar_reader.Next()
    if err == io.EOF {
        break
    } else if err != nil {
        log.Panicf("Cannot read file inside tarball %v", err);
        return 0, err
    } else {
        log.Println("Parsing file : ", header.Name)
        files = append(files, tar_reader)
    }
}
reader = io.MultiReader(files...)
writer, err := os.Create(target)
if err != nil {
    log.Panicf("Cannot write unarchived file %v", err);
    return 0, err
}
defer writer.Close()

result,err := io.Copy(writer, reader)
if(err != nil) {
    log.Panicf("Cannot write unarchived file %v", err);
}
return result,err

While I am not getting any error with the above code, the files are just not read. The output has no data. Please point me on where I am going wrong.

答案1

得分: 2

你正在将相同的tar.Reader多次附加到files切片中。在读取头部后,你必须从存档中读取文件。只需在那一点上复制文件。你可能还应该检查常规文件与目录、符号链接等之间的区别。

copied := 0
for {
    header, err := tar_reader.Next()
    if err == io.EOF {
        break
    } else if err != nil {
        log.Fatalf("无法读取tarball中的文件 %v", err)
    }

    if !(header.Typeflag == tar.TypeReg || header.Typeflag == tar.TypeRegA) {
        continue
    }

    n, err = io.Copy(writer, tar_reader)
    if err != nil {
        log.Fatalf("无法写入未归档的文件 %v", err)
    }
    copied += n
}
return copied, nil
英文:

You're appending the same tar.Reader over and over to the files slice. You have to read the file from the archive after you read the header. Just copy the files at that point. You probably should check for regular files too, vs directories, symlinks, etc.

copied := 0
for {
	header, err := tar_reader.Next()
	if err == io.EOF {
		break
	} else if err != nil {
		log.Fatalf("Cannot read file inside tarball %v", err)
	}

    if !(header.Typeflag == tar.TypeReg || header.Typeflag == tar.TypeRegA) {
        continue
    }


	n, err = io.Copy(writer, tar_reader)
	if err != nil {
		log.Fatalf("Cannot write unarchived file %v", err)
	}
	copied += n
}
return copied, nil

huangapple
  • 本文由 发表于 2016年10月28日 22:19:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/40307143.html
匿名

发表评论

匿名网友

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

确定