英文:
Read contents of tar file without unzipping to disk
问题
我已经能够循环遍历tar文件中的文件,但我卡在如何将这些文件的内容读取为字符串上。我想知道如何将文件的内容作为字符串打印出来?
以下是我的代码:
package main
import (
"archive/tar"
"fmt"
"io"
"log"
"os"
"bytes"
"compress/gzip"
)
func main() {
file, err := os.Open("testtar.tar.gz")
archive, err := gzip.NewReader(file)
if err != nil {
fmt.Println("There is a problem with os.Open")
}
tr := tar.NewReader(archive)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Contents of %s:\n", hdr.Name)
}
}
请注意,这只是打印了文件的名称,如果你想要打印文件的内容作为字符串,你需要在循环中添加读取文件内容的代码。
英文:
I have been able to loop through the files in a tar file, but I am stuck on how to read the contents of those files as string. I would like to know how to print the contents of the files as a string?
This is my code below
package main
import (
"archive/tar"
"fmt"
"io"
"log"
"os"
"bytes"
"compress/gzip"
)
func main() {
file, err := os.Open("testtar.tar.gz")
archive, err := gzip.NewReader(file)
if err != nil {
fmt.Println("There is a problem with os.Open")
}
tr := tar.NewReader(archive)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Contents of %s:\n", hdr.Name)
}
}
答案1
得分: 16
只需将tar.Reader用作要读取的每个文件的io.Reader。
tr := tar.NewReader(r)
// 获取下一个文件条目
h, _ := tr.Next()
如果您需要将整个文件作为字符串:
// 将文件h.Name的完整内容读取到bs []byte中
bs, _ := ioutil.ReadAll(tr)
// 将[]byte转换为字符串
s := string(bs)
如果您需要逐行读取,则可以使用以下方法:
// 创建用于逐行读取的Scanner
s := bufio.NewScanner(tr)
// 逐行读取循环
for s.Scan() {
// 读取当前最后一行文本
l := s.Text()
// ...并对l进行处理
}
// 此时应检查错误
if s.Err() != nil {
// 处理错误
}
英文:
Just use the tar.Reader as an io.Reader for each file you want to read.
tr := tar.NewReader(r)
// get the next file entry
h, _ := tr.Next()
If you need the whole file as a string:
// read the complete content of the file h.Name into the bs []byte
bs, _ := ioutil.ReadAll(tr)
// convert the []byte to a string
s := string(bs)
If you need to read line by line, then this would be better:
// create a Scanner for reading line by line
s := bufio.NewScanner(tr)
// line reading loop
for s.Scan() {
// read the current last read line of text
l := s.Text()
// ...and do something with l
}
// you should check for error at this point
if s.Err() != nil {
// handle it
}
答案2
得分: 1
有时候我看到人们使用tar.gz
作为临时数据库,所以我觉得将存档读入fstest.MapFS
很有用:
package main
import (
"archive/tar"
"compress/gzip"
"io"
"os"
"testing/fstest"
)
func tarGzMemory(source string) (fstest.MapFS, error) {
file, err := os.Open(source)
if err != nil { return nil, err }
defer file.Close()
gzRead, err := gzip.NewReader(file)
if err != nil { return nil, err }
tarRead := tar.NewReader(gzRead)
files := make(fstest.MapFS)
for {
cur, err := tarRead.Next()
if err == io.EOF { break } else if err != nil { return nil, err }
if cur.Typeflag != tar.TypeReg { continue }
data, err := io.ReadAll(tarRead)
if err != nil { return nil, err }
files[cur.Name] = &fstest.MapFile{Data: data}
}
return files, nil
}
示例:
package main
func main() {
m, e := tarGzMemory("mingw64.db.tar.gz")
if e != nil {
panic(e)
}
data := m["mingw-w64-x86_64-gcc-10.2.0-10/desc"].Data
print(string(data))
}
https://golang.org/pkg/testing/fstest
英文:
Sometimes I have seen people use tar.gz
as a makeshift database, so I found it
useful to read the archive into a fstest.MapFS
:
package main
import (
"archive/tar"
"compress/gzip"
"io"
"os"
"testing/fstest"
)
func tarGzMemory(source string) (fstest.MapFS, error) {
file, err := os.Open(source)
if err != nil { return nil, err }
defer file.Close()
gzRead, err := gzip.NewReader(file)
if err != nil { return nil, err }
tarRead := tar.NewReader(gzRead)
files := make(fstest.MapFS)
for {
cur, err := tarRead.Next()
if err == io.EOF { break } else if err != nil { return nil, err }
if cur.Typeflag != tar.TypeReg { continue }
data, err := io.ReadAll(tarRead)
if err != nil { return nil, err }
files[cur.Name] = &fstest.MapFile{Data: data}
}
return files, nil
}
Example:
package main
func main() {
m, e := tarGzMemory("mingw64.db.tar.gz")
if e != nil {
panic(e)
}
data := m["mingw-w64-x86_64-gcc-10.2.0-10/desc"].Data
print(string(data))
}
答案3
得分: -1
通过官方网站的帮助,这是我之前打算的代码。特别关注底部的字节转换为字符串的部分。
package main
import (
"archive/tar"
"fmt"
"io"
"log"
"os"
"bytes"
"compress/gzip"
)
func main() {
file, err := os.Open("testtar.tar.gz")
archive, err := gzip.NewReader(file)
if err != nil {
fmt.Println("There is a problem with os.Open")
}
tr := tar.NewReader(archive)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Contents of %s:\n", hdr.Name)
//Using a bytes buffer is an important part to print the values as a string
bud := new(bytes.Buffer)
bud.ReadFrom(tr)
s := bud.String()
fmt.Println(s)
fmt.Println()
}
}
帮助完成翻译后,请将翻译结果返回给我。
英文:
With some help from the official site this is what I had intended previously. Special focus should be turned to the bottom where the conversion from bytes to string is made.
package main
import (
"archive/tar"
"fmt"
"io"
"log"
"os"
"bytes"
"compress/gzip"
)
func main() {
file, err := os.Open("testtar.tar.gz")
archive, err := gzip.NewReader(file)
if err != nil {
fmt.Println("There is a problem with os.Open")
}
tr := tar.NewReader(archive)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Contents of %s:\n", hdr.Name)
//Using a bytes buffer is an important part to print the values as a string
bud := new(bytes.Buffer)
bud.ReadFrom(tr)
s := bud.String()
fmt.Println(s)
fmt.Println()
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论