2 回答

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超5個(gè)贊
請注意,錯(cuò)誤表示輸入后偏移處的數(shù)據(jù)已損壞。那是因?yàn)槟鷱奈募凶x取的方式:
buf := make([]byte, 100000)
n, readErr := f.Read(buf)
if readErr != nil {
log.Fatalf("readErr=%v\n", readErr)
}
fmt.Printf("Read bytes, n=%v\n", n)
buffer := bytes.NewBuffer(buf)
zlibReader, zlibErr := zlib.NewReader(buffer)
if zlibErr != nil {
log.Fatalf("zlibErr=%v\n", zlibErr)
}
buf := make([]byte, 100000)將制作一個(gè) 100000 字節(jié)的切片,全部為 0。但在all.in. 由于您從不縮短切片,因此閱讀器將在有效數(shù)據(jù)之后遇到幾千個(gè)零并斷定它已損壞。這就是你得到輸出和錯(cuò)誤的原因。
至于流媒體。在 TCP/UDP 連接的情況下,您應(yīng)該能夠?qū)?a 連接傳遞io.Reader給zlib.NewReader. 為了模擬相同的內(nèi)容,我在修改后的代碼中使用了io.Pipe:
package main
import (
"bytes"
"compress/zlib"
"fmt"
"io"
"log"
"os"
otherzlib "github.com/4kills/go-zlib"
)
func main() {
all()
stream()
// Alas it hangs :(
// otherZlib()
}
func all() {
fmt.Println("==== RUNNING DECOMPRESSION OF all.in")
fmt.Println("")
buf, readErr := os.ReadFile("./chunks/all.in")
if readErr != nil {
log.Fatalf("readErr=%v\n", readErr)
}
fmt.Printf("Read bytes, n=%v\n", len(buf))
buffer := bytes.NewBuffer(buf)
zlibReader, zlibErr := zlib.NewReader(buffer)
if zlibErr != nil {
log.Fatalf("zlibErr=%v\n", zlibErr)
}
out := new(bytes.Buffer)
written, copyErr := io.Copy(out, zlibReader)
if copyErr != nil {
log.Printf("copyErr=%v\n", copyErr)
}
fmt.Printf("Written bytes, n=%v, out:\n%v\n", written, out.String())
fmt.Println("")
}
func stream() {
fmt.Println("==== RUNNING DECOMPRESSION OF SEPARATE CHUNKS")
fmt.Println("")
pRead, pWrite := io.Pipe()
go func() {
buf, readErr := os.ReadFile("./chunks/0.in")
if readErr != nil {
log.Fatalf("readErr=%v\n", readErr)
}
fmt.Printf("Read 0 bytes, n=%v\n", len(buf))
written0, copy0Err := io.Copy(pWrite, bytes.NewBuffer(buf))
if copy0Err != nil {
log.Printf("copy0Err=%v\n", copy0Err)
}
fmt.Printf("Written compressed bytes, n0=%v", written0)
buf, readErr = os.ReadFile("./chunks/1.in")
if readErr != nil {
log.Fatalf("read1Err=%v\n", readErr)
}
fmt.Printf("Read 1 bytes, n=%v\n", len(buf))
written1, copy1Err := io.Copy(pWrite, bytes.NewBuffer(buf))
if copy1Err != nil {
log.Printf("copy1Err=%v\n", copy1Err)
}
fmt.Printf("Written compressed bytes, n1=%v", written1)
pWrite.Close()
}()
zlibReader, zlibErr := zlib.NewReader(pRead)
if zlibErr != nil {
log.Fatalf("zlibErr=%v\n", zlibErr)
}
out := new(bytes.Buffer)
written2, copy2Err := io.Copy(out, zlibReader)
if copy2Err != nil {
log.Printf("copy2Err=%v\n", copy2Err)
}
fmt.Printf("Written decompressed bytes, n0=%v, out:\n%v\n", written2, out.String())
fmt.Println("")
}
使用此代碼,我沒有收到任何錯(cuò)誤,stream()但我仍然收到copyErr=unexpected EOF錯(cuò)誤all(),看起來最后all.in缺少校驗(yàn)和數(shù)據(jù),但我認(rèn)為這只是一個(gè)意外。

TA貢獻(xiàn)1893條經(jīng)驗(yàn) 獲得超10個(gè)贊
通過仔細(xì)調(diào)試,我能夠看到我錯(cuò)誤地傳遞了太大的緩沖區(qū)切片,這導(dǎo)致不正確的輸入緩沖區(qū)被饋送到解壓縮。
此外,重要的是不要使用io.Copy
,這會(huì)導(dǎo)致緩沖區(qū)上的 EOF 停止一切,而是只使用 zlibReader.Read(),這將解壓縮當(dāng)前在緩沖區(qū)中的所有內(nèi)容。
我已經(jīng)更新了代碼,所以它現(xiàn)在可以按預(yù)期工作。
- 2 回答
- 0 關(guān)注
- 285 瀏覽
添加回答
舉報(bào)