英文:
ReadAll from File not working as Expected
问题
我正在尝试创建一个临时的gzip文件并将数据写入文件。问题是我不理解ReadAll的工作原理。我期望ReadAll返回写入文件的字节...但实际上没有返回任何字节。然而,File.Stat命令显示确实有数据。
以下是代码的翻译:
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))
为什么没有返回字节?
如何获取返回的字节?
英文:
I am trying to create a temporary gzip file and write to the file. The problem is that I am not understanding what is going on with ReadAll. I expected ReadAll to return the bytes written to the file... however there are none. Yet the File.Stat command shows that there is indeed data.
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))
Here is a playground link https://play.golang.org/p/zX8TSCAbRL
Why are there no returned bytes?
How do I get the returned bytes?
答案1
得分: 3
在读取文件之前关闭它。
根据gzip的文档:
Write将p的压缩形式写入底层的io.Writer。压缩的字节不一定会在Writer关闭之前刷新。
因此,在尝试读取字节数之前,需要同时关闭gzip Writer和底层的io.Writer。
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))
}
英文:
Close the file before reading it.
From the documentation of gzip:
> Write writes a compressed form of p to the underlying io.Writer. The compressed bytes are not necessarily flushed until the Writer is closed.
The solution therefore is to Close
both the gzip Writer as well as the underlying io.Writer before attempting to read the number of bytes.
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))
}
View on Playground.
答案2
得分: 1
你必须seek
文件的开头:
_, _ = file.Seek(0, 0)
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
fmt.Println(err)
}
请查看Playground
英文:
Yo must seek
the start of the file:
_, _ = file.Seek(0, 0)
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
fmt.Println(err)
}
Check the Playground
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论