Golang:为什么 compress/gzip 的 Read 函数不读取文件内容?

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

Golang: Why does the compress/gzip Read function not read file contents?

问题

我创建了一个文本文件,然后用gzip进行了压缩。然后我运行了下面的go程序来读取该压缩文件的内容。

package main

import (
    "compress/gzip"
    "fmt"
    "os"
)

func main() {
    handle, err := os.Open("zipfile.gz")
    if err != nil {
        fmt.Println("[ERROR] 文件打开错误:", err)
    }
    defer handle.Close()

    zipReader, err := gzip.NewReader(handle)
    if err != nil {
        fmt.Println("[ERROR] 新建gzip读取器错误:", err)
    }
    defer zipReader.Close()

    var fileContents []byte
    bytesRead, err := zipReader.Read(fileContents)
    if err != nil {
        fmt.Println("[ERROR] 读取gzip文件错误:", err)
    }
    fmt.Println("[INFO] 从文件中读取的字节数:", bytesRead)
    fmt.Printf("[INFO] 未压缩内容: '%s'\n", fileContents)
}

我得到的响应如下:

$ go run zipRead.go
[INFO] 从文件中读取的字节数: 0
[INFO] 未压缩内容: ''

为什么我没有从文件中获取到任何内容?

我在OS X和Ubuntu上创建了zip文件,并在两个操作系统上构建了相同的go程序,但结果相同。

英文:

I made a text file, that I then compressed with gzip. I then run the following go program to read the contents of that compressed file.

package main

import (
    "compress/gzip"
    "fmt"
    "os"
)

func main() {
    handle, err := os.Open("zipfile.gz")
    if err != nil {
        fmt.Println("[ERROR] File Open:", err)
    }
    defer handle.Close()

    zipReader, err := gzip.NewReader(handle)
    if err != nil {
        fmt.Println("[ERROR] New gzip reader:", err)
    }
    defer zipReader.Close()

    var fileContents []byte
    bytesRead, err := zipReader.Read(fileContents)
    if err != nil {
        fmt.Println("[ERROR] Reading gzip file:", err)
    }
    fmt.Println("[INFO] Number of bytes read from the file:", bytesRead)
    fmt.Printf("[INFO] Uncompressed contents: '%s'\n", fileContents)
}

The response that I get is the following:

$ go run zipRead.go
[INFO] Number of bytes read from the file: 0
[INFO] Uncompressed contents: ''

Why am I not getting any contents from the file?

I have created zip files on both OS X and Ubuntu. I have build this go program on both OS X and Ubuntu with the same result.

答案1

得分: 4

io.Reader.Read 只会读取最多 len(b) 字节。由于你的 fileContents 是空的,它的长度为 0。为其分配一些空间以便读取:

fileContents := make([]byte, 1024) // 每次读取 1 KiB。
bytesRead, err := zipReader.Read(fileContents)
if err != nil {
	fmt.Println("[ERROR] 读取 gzip 文件:", err)
}
fileContents = fileContents[:bytesRead]

如果你想读取整个文件,你需要多次使用 Read,或者使用 ioutil.ReadAll(对于大文件可能不太好)。

英文:

io.Reader.Read will only read up to len(b) bytes. Since your fileContents is nil, its length is 0. Allocate some space for it to read into:

fileContents := make([]byte, 1024) // Read by 1 KiB.
bytesRead, err := zipReader.Read(fileContents)
if err != nil {
	fmt.Println("[ERROR] Reading gzip file:", err)
}
fileContents = fileContents[:bytesRead]

If you want to read the whole file, you'll have to either use Read several times, or use things like ioutil.ReadAll (which may be bad for big files).

huangapple
  • 本文由 发表于 2015年8月15日 04:26:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/32018130.html
匿名

发表评论

匿名网友

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

确定