go - Golang 意外的 EOF
问题描述
这是我的代码,我是 Go 新手。我试着用谷歌搜索这个问题,但我不能完全解决这个问题。我认为这与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] Uncompressed data: 2364480 2018/06/29 21:41:35 unexpected EOF
解决方案
在对有问题的特定代码进行跟踪之后,我得出了以下答案。
func (r *Reader) ReadByte() (byte, error) {
...
if r.i >= int64(len(r.s)) {
return 0, io.EOF
}
....
}
bytes/reader 中有四个函数可以返回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
,flate/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
推荐阅读
- javascript - 字段名称包含空格时的猫鼬排序?
- google-chrome - 在 Google 计算器上设置容差
- html - 强制行内块元素水平滚动,同时仍允许垂直滚动
- react-native - 无法解析模块 ./Transitioning with react-native-reanimated
- python - 在while循环中计算平均值
- visual-studio - 是否可以仅为特定项目自动启动 WCF?
- react-native - 当用户点击它时,TouchableOpacity 没有显示任何 UI 效果
- leaflet - 传单:如何添加标记以仅在将鼠标悬停在另一个标记上时进行映射?
- memory-management - 在给定地址分配堆内存
- react-native - 检测用户何时移动到特定屏幕