Golang:将xml转换为gzip时出现问题 [英] Golang : Problem in converting xml to gzip

查看:107
本文介绍了Golang:将xml转换为gzip时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用golang将xml文件压缩为gzip的程序。

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

但是该程序无法生成文件,但是当我尝试时它确实会生成输出将.txt文件转换为gzip。
这是我的程序:-

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)
    }

}

如何生成所需的.gz文件。

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

推荐答案

现在, zw.Write()调用会将(压缩的)数据写入 buff 。既然相反,您想将其写入文件,则应该创建可以完成此操作的东西。

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.

最简单的方法是使用 os .Create()。此函数返回 * os.File ,该文件实现了 io.Writer

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

生成的代码如下:

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
    }
}

这种编写作者的方式使更改变得非常容易事情如何进行而无需更改太多代码。您可以更进一步,因为 * xml.Encoder 也是 io.Writer 的实现。另一个 io.Writer 作为参数,就像 * gzip.Writer 一样。因此,要实际生成XML并将其写入文件并将其gzip压缩,只需执行以下操作:

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.

这篇关于Golang:将xml转换为gzip时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆