[英]Golang unexpected EOF
這是我的代碼,我是Go的新手。 我曾嘗試使用Google搜索該問題,但我對此完全沒有把握。 我認為這與Read()方法有關。
package main
import (
...
)
type compressor struct {
content []byte
}
func (r *compressor) compress() []byte {
...
}
func (r *compressor) decompress() []byte {
var buffer bytes.Buffer
dc := flate.NewReader(&buffer)
_, err := dc.Read(r.content)
if err != nil {
if err != io.EOF {
log.Fatal(err)
}
}
return buffer.Bytes()
}
func main() {
fileName := os.Args[1]
fmt.Println(os.Args)
contents, err := ioutil.ReadFile(fileName)
if err != nil {
log.Fatal(err)
}
fmt.Print("Uncompressed data: ")
fmt.Println(len(contents))
comp := compressor{contents}
buffer := comp.decompress()
fmt.Print("Uncompressed data: ")
fmt.Println(len(comp.decompress()))
err = ioutil.WriteFile(fileName+".decjc", buffer, 0644)
if err != nil {
log.Fatal(err)
}
}
這是輸出
dylan @ skynet:〜/ Documents / EXP / jc $ ./jc data.txt.jc
[./jc data.txt.jc]
未壓縮數據:2364480
2018/06/29 21:41:35意外的EOF
您進入了,輸出混合了。
flate.NewReader
將壓縮后的輸入作為io.Reader
並返回io.ReadCloser
,可用於獲取未壓縮的輸出:
func (r *compressor) decompress() []byte {
dc := flate.NewReader(bytes.NewReader(r.content))
defer dc.Close()
rb, err := ioutil.ReadAll(dc)
if err != nil {
if err != io.EOF {
log.Fatalf("Err %v\n read %v", err, rb)
}
}
return rb
}
在對有問題的特定代碼進行跟蹤之后,我得到了以下答案。
func (r *Reader) ReadByte() (byte, error) {
...
if r.i >= int64(len(r.s)) {
return 0, io.EOF
}
....
}
字節/讀取器中有四個函數可以返回io.EOF
,而零個函數可以返回io.ErrUnexpectedEOF
。 可以返回io.EOF
的四個函數是:
Read(b []byte)
ReadAt(b []byte, off int64)
ReadByte()
ReadRune()
/src/compress/flate/inflate.go 698
func (f *decompressor) moreBits() error {
c, err := f.r.ReadByte()
if err != nil {
return noEOF(err)
}
...
}
在可以返回io.EOF
的四個函數中,只有io.EOF
/ inflate.go中的一個函數調用其中任何一個: moreBits()
調用ReadByte()
/src/compress/flate/inflate.go 690
func noEOF(e error) error {
if e == io.EOF {
return io.ErrUnexpectedEOF
}
...
}
當moreBits()
收到錯誤時,它將調用noEOF()
,該方法將檢查是否已收到io.EOF
。 如果是這種情況,則返回io.ErrUnexpectedEOF
。 一切似乎都按預期進行,似乎需要用戶注意這種特殊情況。 建議對上面的代碼進行編輯,以處理似乎已定義的行為:
func (r *compressor) decompress() []byte {
dc := flate.NewReader(bytes.NewReader(r.content))
defer dc.Close()
rb, err := ioutil.ReadAll(dc)
if err != nil {
if err != io.EOF && err != io.ErrUnexpectedEOF {
log.Fatalf("Err %v\n read %v", err, rb)
}
}
return rb
}
這在go1.12.9
下進行了檢查
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.