Golang : Problem in converting xml to gzip

寵の児 提交于 2020-01-30 13:02:21

问题


I am working on a program that compresses xml files to gzip using golang.

but the program failed to generate files, however it does generate the output when I try to convert .txt file to gzip . Here is my program:-

package main

import (
    "bytes"
    "compress/gzip"
    "fmt"
    "io"
    "log"
    "os"
)

type Notes struct {
    To      string `xml:"to"`
    From    string `xml:"from"`
    Heading string `xml:"heading"`
    Body    string `xml:"body"`
}

func main() {
    var buf bytes.Buffer
    zw := gzip.NewWriter(&buf)

    // Setting the Header fields is optional.
    zw.Name = "new.xml"

    _, err := zw.Write([]byte("Compressing"))
    if err != nil {
        log.Fatal(err)
    }

    if err := zw.Close(); err != nil {
        log.Fatal(err)
    }

    zr, err := gzip.NewReader(&buf)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Name: %s", zr.Name)

    if _, err := io.Copy(os.Stdout, zr); err != nil {
        log.Fatal(err)
    }

    if err := zr.Close(); err != nil {
        log.Fatal(err)
    }

}

What should I do for generating the .gz file I desire.


回答1:


Right now, zw.Write() calls will write the (compressed) data into buff. Since, instead, you want to write it to a file, you should create something that does just that.

The easiest way is to use os.Create(). This function returns a *os.File, which implements io.Writer.

The resulting code would be something like this:

package main

import (
    "compress/gzip"
    "log"
    "os"
)

func main() {
    //  This creates a file and returns an implementation of io.Writer
    fileWriter, err := os.Create("./file.gz")
    if err != nil {
        log.Println(err)
        return
    }
    defer fileWriter.Close()

    //  Use the io.Writer to create the gzip.Writer.
    zw := gzip.NewWriter(fileWriter)
    defer zw.Close()

    // Setting the Header fields is optional.
    zw.Name = "new.xml"

    //  When gzip.Writer.Write is called, it will pass on the data to the Write func of the io.Writer we passed on line 17.
    //  If there is an error writing to the actual file, it will be returned.
    _, err = zw.Write([]byte("Compressing"))
    if err != nil {
        log.Println(err)
        return
    }
}

This way of composing writers makes it very easy to change how things work without changing to much code. You can take this composition a step further, because *xml.Encoder is also an implementation of io.Writer that takes another io.Writer as parameter, just like *gzip.Writer does. So to actually generate and write XML to a file and gzip it along the way, you would just do the following:

package main

import (
    "compress/gzip"
    "encoding/xml"
    "log"
    "os"
)

type Notes struct {
    To      string `xml:"to"`
    From    string `xml:"from"`
    Heading string `xml:"heading"`
    Body    string `xml:"body"`
}

func main() {
    //  This creates a file and returns *os.File, an implementation of io.Writer
    fileWriter, err := os.Create("./notes.gz")
    if err != nil {
        log.Println(err)
        return
    }
    defer fileWriter.Close()

    //  Use the io.Writer to create the gzip.Writer.
    zw := gzip.NewWriter(fileWriter)
    defer zw.Close()

    // Setting the Header fields is optional.
    zw.Name = "notes.xml"

    notes := []Notes{
        {
            To:      "Alice",
            From:    "Bob",
            Heading: "Hi",
            Body:    "Hey Alice, how are you?",
        },
        {
            To:      "Bob",
            From:    "Alice",
            Heading: "Re: Hi",
            Body:    "Hi Bob! I'm fine, thnx.",
        },
    }

    // Create the xml.Encoder, using the gzip.Writer (which implements io.Writer).
    xmlWriter := xml.NewEncoder(zw)
    // So now, we have an xml.Encoder which writes to a gzip.Writer which writes to io.File.

    // This call to Encode() will generate the XML, pass that to gzip.Writer.Write, which passes it to os.File.Write.
    err = xmlWriter.Encode(notes)
    if err != nil {
        log.Println(err)
        return
    }
}

This way of composing writers (as well as readers) is very powerful. You can find it in a lot of places, making is very easy to "layer" writers.



来源:https://stackoverflow.com/questions/59785830/golang-problem-in-converting-xml-to-gzip

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!