2015-08-14 68 views
1

我做了一個文本文件,然後我用gzip壓縮。然後運行以下go程序來讀取該壓縮文件的內容。Golang:爲什麼compress/gzip Read函數沒有讀取文件內容?

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) 
} 

,我得到的迴應是:

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

爲什麼我沒有得到從文件中的任何內容?

我在OS X和Ubuntu上都創建了zip文件。我在OS X和Ubuntu上構建了這個go程序,結果相同。

+1

除了[@JimB says](http://stackoverflow.com/a/32018378/55504)之外,您還錯誤地使用了'Read'。你需要傳遞一個你想要它放入字節的分配片,你傳遞一個零片('len(fileContents)== 0,所以你要求零字節)。 –

回答

3

io.Reader.Read只會讀取最多len(b)字節。由於您的fileContents是零,它的長度爲0分配一些空間,其讀入:

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] 

如果你想閱讀整個文件,你必須要麼使用Read幾次,或使用的東西像ioutil.ReadAll(這可能對大文件不利)。

+3

注意讀取更少的字節後可以返回「Read」也很重要。如果您需要讀取正在使用的完整字節片['io.ReadFull'](https://golang.org/pkg/io/#ReadFull);如果你想要完整的內容使用['ioutil.ReadAll'](https://golang.org/pkg/io/ioutil/#ReadAll)(但是除非你真的需要預先閱讀整個內容,否則就避免這樣做)。 –

+0

我最終使用'ioutil.ReadAll'。但我仍然好奇爲什麼gzip「Read」無法正常工作。這有助於我理解。如果在[文檔頁面](http://golang.org/pkg/compress/gzip/#Reader.Read)中提到這會很有幫助。但是,如果我對'io.Reader'有了更好的理解,我想它會被假設爲知識。 – SunSparc

相關問題