これが私のコードです。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
}
....
}
io.EOF
を返すことができるバイト/リーダーの4つの関数と、io.ErrUnexpectedEOF
を返すことができるゼロの関数があります。 io.EOF
を返すことができる4つの関数は次のとおりです。
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
を返すことができる4つの関数のうち、flate/inflate.go内の1つの関数だけがそれらの関数を呼び出します。moreBits()
はReadByte()
を呼び出します
/ src/compress/flate/inflate.go 69
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
で確認されました
あなたはインとアウトプットを混ぜ合わせました。
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
}