【问题标题】:Transparent (filter-like) gzip/gunzip in GoGo 中的透明(类似过滤器)gzip/gunzip
【发布时间】:2013-12-02 02:42:25
【问题描述】:

我正在尝试,只是为了好玩,将 gzip Writer 直接连接到 gzip Reader,这样我就可以写入 Writer 并即时从 Reader 读取。我希望能准确地阅读我所写的内容。我正在使用 gzip,但我也想将此方法与 crypto/aes 一起使用,我想它的工作方式应该非常相似,并且可以与 jpeg、png 等其他读取器/写入器一起使用...

这是我最好的选择,但不起作用,但我希望你能明白我的意思:http://play.golang.org/p/7qdUi9wwG7

package main

import (
    "bytes"
    "compress/gzip"
    "fmt"
)

func main() {
    s := []byte("Hello world!")
    fmt.Printf("%s\n", s)

    var b bytes.Buffer

    gz := gzip.NewWriter(&b)
    ungz, err := gzip.NewReader(&b)
    fmt.Println("err: ", err)

    gz.Write(s)
    gz.Flush()
    uncomp := make([]byte, 100)
    n, err2 := ungz.Read(uncomp)
    fmt.Println("err2: ", err2)
    fmt.Println("n: ", n)
    uncomp = uncomp[:n]
    fmt.Printf("%s\n", uncomp)
}

gzip.NewReader(&b) 似乎正在尝试立即读取并返回 EOF。

【问题讨论】:

    标签: go


    【解决方案1】:

    你需要做两件事才能让它工作

    1. 使用io.Pipe 将读取器和写入器连接在一起 - 您不能从同一个缓冲区读取和写入
    2. 在单独的 goroutine 中运行读取和写入。因为 gzip 所做的第一件事是尝试读取标头,除非您有另一个 go 例程尝试编写它,否则您会遇到死锁。

    这就是它的样子

    Playground

    func main() {
        s := []byte("Hello world!")
        fmt.Printf("%s\n", s)
    
        in, out := io.Pipe()
    
        gz := gzip.NewWriter(out)
        go func() {
            ungz, err := gzip.NewReader(in)
            fmt.Println("err: ", err)
            uncomp := make([]byte, 100)
            n, err2 := ungz.Read(uncomp)
            fmt.Println("err2: ", err2)
            fmt.Println("n: ", n)
            uncomp = uncomp[:n]
            fmt.Printf("%s\n", uncomp)
        }()
        gz.Write(s)
        gz.Flush()    
    }
    

    【讨论】:

    • 谢谢尼克,这正是我想要的!我想如果我需要链接更多的过滤器,比如压缩、加密和编码,应该在 go func() 中完成。我仍然认为太顺序了。而且我还假设 Flush() 会传播到最后,还是假设太多了?
    • 链接更多过滤器应该没问题,您只需要使用单独的 go 例程将链的开头抽出,然后将内容从末尾取出以避免死锁。请记住,go 中的所有 IO 都是阻塞的,如果您不想阻塞,请使用 go 例程。 Flush 不会沿着管道传播,它只是一个 gzip 的东西。然而,上述缓冲都不是不必要的。
    【解决方案2】:

    使用管道。例如,

    Package io

    func Pipe

    func Pipe() (*PipeReader, *PipeWriter)
    

    Pipe 创建一个同步的内存管道。它可以用来连接 期望 io.Reader 的代码与期望 io.Writer 的代码。继续阅读 一端与另一端的写入匹配,直接复制数据 两者之间;没有内部缓冲。打电话是安全的 彼此并行读取和写入或关闭。关闭意志 待处理的 I/O 完成后完成。并行调用 Read,以及 对 Write 的并行调用也是安全的:单个调用将是 顺序门控。

    【讨论】:

      猜你喜欢
      • 2019-05-14
      • 2021-06-06
      • 2011-09-15
      • 2011-06-15
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      • 2014-03-29
      相关资源
      最近更新 更多