2017-03-02 98 views
-1

我試圖創建一個臨時gzip文件,並寫入文件。問題是我不瞭解ReadAll正在發生什麼。我希望ReadAll能夠返回寫入文件的字節......但是沒有。然而File.Stat命令顯示確實有數據。ReadAll工作不正常

filename := "test" 
file, err := ioutil.TempFile("", filename) 
if err != nil { 
    fmt.Println(err) 
} 
defer func() { 
    if err := os.Remove(file.Name()); err != nil { 
     fmt.Println(err) 
    } 
}() 

w := gzip.NewWriter(file) 
_, err = w.Write([]byte("hell0")) 
if err != nil { 
    fmt.Println(err) 
} 

fileInfo, err := file.Stat() 
if err != nil { 
    fmt.Println(err) 
} 
fileBytes, err := ioutil.ReadAll(file) 
if err != nil { 
    fmt.Println(err) 
} 
if err := w.Close(); err != nil { 
    fmt.Println(err) 
} 
fmt.Println("SIZE1:", fileInfo.Size()) 
fmt.Println("SIZE2:", len(fileBytes)) 

這裏是一個操場鏈接https://play.golang.org/p/zX8TSCAbRL

爲什麼沒有返回的字節? 如何獲取返回的字節?

回答

3

閱讀它之前關閉該文件。

從gzip的的the documentation

寫入寫入p來底層io.Writer的壓縮形式。在Writer關閉之前,壓縮的字節不一定會被刷新。

因此,解決方法是在嘗試讀取字節數之前,將gzip Writer以及底層的io.Writer都寫入Close

func main() { 
     basename := "test" 
     file, err := ioutil.TempFile("", basename) 
     tempFilename := file.Name() 
     if err != nil { 
      fmt.Println(err) 
     } 
     defer func() { 
      if err := os.Remove(file.Name()); err != nil { 
       fmt.Println(err) 
      } 
     }() 

     w := gzip.NewWriter(file) 
     _, err = w.Write([]byte("hell0")) 
     if err != nil { 
      fmt.Println(err) 
     } 

     w.Close() 
     file.Close() 

     file, err = os.Open(tempFilename) 
     fileInfo, err := file.Stat() 
     if err != nil { 
      fmt.Println(err) 
     } 
     fileBytes, err := ioutil.ReadAll(file) 
     if err != nil { 
      fmt.Println(err) 
     } 
     if err := w.Close(); err != nil { 
      fmt.Println(err) 
     } 
     fmt.Println("SIZE1:", fileInfo.Size()) 
     fmt.Println("SIZE2:", len(fileBytes)) 

} 

查看Playground

1

呦必須seek的文件的開頭:

_, _ = file.Seek(0, 0) 
fileBytes, err := ioutil.ReadAll(file) 
if err != nil { 
    fmt.Println(err) 
} 

檢查Playground