From 71c81a7bc9b8fe956a900d2d1aaa37ab34e854be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=89=E5=AD=90?= Date: Tue, 13 Oct 2015 00:08:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=9012.9=E7=AB=A0=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eBook/12.9.md | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 eBook/12.9.md diff --git a/eBook/12.9.md b/eBook/12.9.md new file mode 100644 index 0000000..73e73e2 --- /dev/null +++ b/eBook/12.9.md @@ -0,0 +1,231 @@ +# Json数据格式 + +数据结构要在网络中传输或保存到文件,就必须对其编码和解码;目前存在很多编码格式:JSON,XML,gob,Google缓冲协议等等。Go语言支持所有这些编码格式;在后面的章节,我们将讨论前三种格式。 + +结构能够包含二进制数据,如果作为文本打印,那么可读性是很差的。另外结构内部包含命名字段,所以不清楚数据的用意。 + +通过把数据转换成纯文本,使用命名的字段来标注,让其具有可读性。这样的数据格式可以通过网络传输,而且是与平台无关的,任何类型的应用都能够读取和输出,不用关系操作系统和编程语言的类型。 + +下面是一些术语说明: + +- 数据结构 --> 指定格式 = `序列化`或`编码`(传输之前) +- 指定格式 --> 数据格式 = `反序列化`或`解码`(传输之后) + +序列化是在内存中把数据转换成指定格式(data -> string),反之亦然(string -> data structure) + +编码也是一样的,只是输出一个数据流(实现了io.Writer接口);解码是从一个数据流(实现了io.Reader)输出到一个数据结构。 + +我们都比较熟悉XML格式(参阅12.10);但有些时候JSON(JavaScript Object Notation,参阅 [http://json.org](http://json.org))被作为首选,主要是由于其格式上非常简洁。通常json被用在web后端和浏览器之间通讯,但是在其它场景也同样的有用。 + +这是一个简短的JSON片段: + +```javascript +{ + "Person": { + "FirstName": "Laura", + "LastName": "Lynn" + } +} +``` + +尽管XML被广泛的应用,但是JSON更加简洁、轻量(其占用更少的内存、磁盘及网络带宽)和更好的可读性,这也说明他越来越受欢迎。 + +go语言的json包可以让你在程序中方便的读取和写入JSON数据。 + +我们将在下面的例子里使用json包,并使用练习10.1 vcard.go中一个简化版本的Address和VCard结构(为了简单起见,我们忽略了很多错误处理,不过在实际应用中你必须要合理的处理这些错误,参阅13章) + + +示例 12.16 [json.go](examples/chapter_12/json.go): + +```go +// json.go.go +package main + +import ( + "encoding/json" + "fmt" + "log" + "os" +) + +type Address struct { + Type string + City string + Country string +} + +type VCard struct { + FirstName string + LastName string + Addresses []*Address + Remark string +} + +func main() { + pa := &Address{"private", "Aartselaar", "Belgium"} + wa := &Address{"work", "Boom", "Belgium"} + vc := VCard{"Jan", "Kersschot", []*Address{pa, wa}, "none"} + // fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}: + // JSON format: + js, _ := json.Marshal(vc) + fmt.Printf("JSON format: %s", js) + // using an encoder: + file, _ := os.OpenFile("vcard.json", os.O_CREATE|os.O_WRONLY, 0) + defer file.Close() + enc := json.NewEncoder(file) + err := enc.Encode(vc) + if err != nil { + log.Println("Error in encoding json") + } +} + +``` + +`json.Marshal()`的函数签名是 `func Marshal(v interface{}) ([]byte, error)`,下面是数据编码后的json文本(实际上是一个[]bytes): + +```javascript +{ + "FirstName": "Jan", + "LastName": "Kersschot", + "Addresses": [{ + "Type": "private", + "City": "Aartselaar", + "Country": "Belgium" + }, { + "Type": "work", + "City": "Boom", + "Country": "Belgium" + }], + "Remark": "none" +} +``` + +处于安全考虑,在web应用中最好使用`json.MarshalforHTML()`函数,其对数据执行HTML转码,所以文本会被安全的嵌在HTML`