go学习------文件处理

一、JSON

​ Go语言内建对 JSON 的支持,使用内置的 encoding/json 标准库,开发人员可以轻松使用Go程序生成和解析 JSON 格式的数据。

​ json.NewEncoder(filePtr) 创建Json编码器 encoder.Encode(info)

​ json.NewDecoder(filePtr1) 创建Json解码器 decoder.Decode(&info)

import (
    "encoding/json"
    "fmt"
    "os"
)
type Website struct {
    Name   string `xml:"name,attr"`
    Url    string
    Course []string
}
func main() {
    info := []Website{{"Golang", "http://c.biancheng.net/golang/", []string{"http://c.biancheng.net/cplus/", "http://c.biancheng.net/linux_tutorial/"}}, {"Java", "http://c.biancheng.net/java/", []string{"http://c.biancheng.net/socket/", "http://c.biancheng.net/python/"}}}
     
    str,_:=os.Getwd()      //获取当前目录
	fmt.Println(str)
    filePtr, err := os.Create("info.json")    //创建文件,在当前目录下创建
    if err != nil {
        fmt.Println("文件创建失败", err.Error())
        return
    }
    defer filePtr.Close()
    
    //编码
    encoder := json.NewEncoder(filePtr)    // 创建Json编码器
    err = encoder.Encode(info)
    if err != nil {
        fmt.Println("编码错误", err.Error())
    } else {
        fmt.Println("编码成功")
	}
}
import (
    "encoding/json"
    "fmt"
    "os"
)
type Website struct {
    Name   string `xml:"name,attr"`
    Url    string
    Course []string
}

func main() {
	filePtr1,err := os.Open("./info.json")     //.表示当前目录
	if err != nil{
		fmt.Println("文件打开失败",err.Error())
		return
	}
	defer filePtr1.Close()
    
    //解码
	var info1 []Website
	decoder := json.NewDecoder(filePtr1)   // 创建json解码器
	err = decoder.Decode(&info1)
	if err !=nil {
		fmt.Println("解码失败",err.Error())
	} else {
		fmt.Println("解码成功")
		fmt.Println(info1)
	}
}
二、XML

​ Go语言内置的 encoding/xml 包可以用在结构体和 XML 格式之间进行编解码,其方式跟 encoding/json 包类似。然而与 JSON 相比 XML 的编码和解码在功能上更苛刻得多,这是由于 encoding/xml 包要求结构体的字段包含格式合理的标签,而 JSON 格式却不需要。

​ encoder := xml.NewEncoder(filePtr) encoder.Encode(info)

​ decoder := xml.NewDecoder(filePtr) decoder.Decode(&info)

import (
	"encoding/xml"
	"fmt"
	"os"
)

type Website struct {
    Name   string `xml:"name,attr"`
    Url    string
    Course []string
}

func main(){
	info := Website{"C语言中文网", "http://c.biancheng.net/golang/", []string{"Go语言入门教程", "Golang入门教程"}}
	f,err := os.Create("./info.xml")
	if err != nil{
		fmt.Println("文件创建失败",err.Error())
		return
	}
	defer f.Close()
    
    //编码
	encoder := xml.NewEncoder(f)
	err = encoder.Encode(info)
	if err != nil {
		fmt.Println("编码错误",err.Error())
		return
	} else {
		fmt.Println("编码成功")
	}


}
import (
	"encoding/xml"
	"fmt"
	"os"
)

type Website struct {
    Name   string `xml:"name,attr"`
    Url    string
    Course []string
}

func main(){ 
	file,err := os.Open("./info.xml")
	if err != nil{
		fmt.Println("打开文件失败",err.Error())
		return
	}
	defer file.Close()
    //解码
	info1 := Website{} 
	decoder := xml.NewDecoder(file)
	err = decoder.Decode(&info1)
	if err != nil{
		fmt.Println("解码失败",err.Error())
		return
	} else {
		fmt.Println("解码成功")
		fmt.Println(info1)
	}
}

将结构体转换为XML输出时,需要注意以下规则:

  • XMLName字段,如上所述,会省略
  • 具有标签"-"的字段会省略
  • 具有标签"name,attr"的字段会成为该XML元素的名为name的属性
  • 具有标签",attr"的字段会成为该XML元素的名为字段名的属性
  • 具有标签",chardata"的字段会作为字符数据写入,而非XML元素
  • 具有标签",innerxml"的字段会原样写入,而不会经过正常的序列化过程
  • 具有标签",comment"的字段作为XML注释写入,而不经过正常的序列化过程,该字段内不能有"–"字符串
  • 标签中包含"omitempty"选项的字段如果为空值会省略
    空值为false、0、nil指针、nil接口、长度为0的数组、切片、映射
  • 匿名字段(其标签无效)会被处理为其字段是外层结构体的字段
  • 如果一个字段的标签为"a>b>c",则元素c将会嵌套进其上层元素a和b中。如果该字段相邻的字段标签指定了同样的上层元素,则会放在同一个XML元素里。

解析XML编码时,需要遵守以下规则:

  • 如果结构体字段的类型为字符串或者[]byte,且标签为",innerxml",
    Unmarshal函数直接将对应原始XML文本写入该字段,其余规则仍适用。
  • 如果结构体字段类型为xml.Name且名为XMLName,Unmarshal会将元素名写入该字段
  • 如果字段XMLName的标签的格式为"name"或"namespace-URL name",
    XML元素必须有给定的名字(以及可选的名字空间),否则Unmarshal会返回错误。
  • 如果XML元素的属性的名字匹配某个标签",attr"为字段的字段名,或者匹配某个标签为"name,attr"的字段的标签名,Unmarshal会将该属性的值写入该字段。
  • 如果XML元素包含字符数据,该数据会存入结构体中第一个具有标签",chardata"的字段中,
    该字段可以是字符串类型或者[]byte类型。如果没有这样的字段,字符数据会丢弃。
  • 如果XML元素包含注释,该数据会存入结构体中第一个具有标签",comment"的字段中,
    该字段可以是字符串类型或者[]byte类型。如果没有这样的字段,字符数据会丢弃。
  • 如果XML元素包含一个子元素,其名称匹配格式为"a"或"a>b>c"的标签的前缀,反序列化会深入XML结构中寻找具有指定名称的元素,并将最后端的元素映射到该标签所在的结构体字段。
    以">“开始的标签等价于以字段名开始并紧跟着”>" 的标签。
  • 如果XML元素包含一个子元素,其名称匹配某个结构体类型字段的XMLName字段的标签名,
    且该结构体字段本身没有显式指定标签名,Unmarshal会将该元素映射到该字段。
  • 如果XML元素的包含一个子元素,其名称匹配够格结构体字段的字段名,且该字段没有任何模式选项(",attr"、",chardata"等),Unmarshal会将该元素映射到该字段。
  • 如果XML元素包含的某个子元素不匹配以上任一条,而存在某个字段其标签为",any",
    Unmarshal会将该元素映射到该字段。
  • 匿名字段被处理为其字段好像位于外层结构体中一样。
  • 标签为"-"的结构体字段永不会被反序列化填写。
三、Gob

​ Gob 是Go语言自己以二进制形式序列化和反序列化程序数据的格式,可以在 encoding 包中找到。这种格式的数据简称为 Gob(即 Go binary 的缩写)。类似于 Python]的“pickle”和 Java的“Serialization”。

​ Gob 特定的用于纯 Go 的环境中,例如两个用Go语言写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。

import (
	"encoding/gob"
	"fmt"
	"os"
)
func main(){
	info := map[string]string{
		"name":"百度",
		"website":"http://baidu.com",
	}
	name := "demo.gob"
	File,_ := os.OpenFile(name,os.O_RDWR|os.O_CREATE,0777)
	defer File.Close()
    
    //编码
	enc := gob.NewEncoder(File)
	if err := enc.Encode(info);err != nil{
		fmt.Println(err)
	}
}
import (
	"encoding/gob"
	"fmt"
	"os"
)
func main(){
	var M map[string]string
	File1, _ := os.Open("demo.gob")
	defer File1.Close()
    
    //解码
    D := gob.NewDecoder(File1)
    D.Decode(&M)
    fmt.Println(M)

}
四、纯文本文件
import (
	"bufio"
	"fmt"
	"os"
	"io"
)
func main(){
	filePath := "./output.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        fmt.Printf("打开文件错误= %v \n", err)
        return
    }
	defer file.Close()
	str := "http://c.biancheng.net/golang/\n"
	writer := bufio.NewWriter(file)     //写入时,使用带缓存的 *Writer
	for i :=0;i<3;i++{
		writer.WriteString(str)
	}
	writer.Flush()   //调用 flush方法,将缓存的数据真正写入到文件中。

	
}
import (
	"bufio"
	"fmt"
	"os"
	"io"
)
func main(){
	file1, err := os.Open("./output.txt")
    if err != nil {
        fmt.Println("文件打开失败 = ", err)
	}
	defer file1.Close()
	reader := bufio.NewReader(file1)
	for{
		str,err := reader.ReadString('\n')
		if err == io.EOF{
			break
		}
		fmt.Print(str)
	}
	fmt.Println("文件读取结束")
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值