go语言文件


前言

介绍各类文件经常用来做什么工作,以及在Go语言中操作各类文件的方法


一、文件类型及作用?

①文件的职能作用

文件一般都有后缀名,根据他的后缀名区分文件的职能类型,比如jpg,png后缀结尾的是照片,txt结尾的是文本文件…
一般的文件大家都知道是用来干什么的就不进行详细阐述了,一下主要讲解一下大家可能不太了解的文件类型,

(1)json文件

JSON文件是用来存储简单的数据结构和对象的文件,可以在web应用程序中进行数据交换
JSON是全称为JavaScript Object Notation,是一种有条理,易于访问的存储信息的方法。

代码如下:

[{
    
    "Name":"Golang",
"Url":"http://c.biancheng.net/golang/","
Course":["http://c.biancheng.net/cplus/","http://c.biancheng.net/linux_tutorial/"]},

{
    
    "Name":"Java",
"Url":"http://c.biancheng.net/java/",
"Course":["http://c.biancheng.net/socket/","http://c.biancheng.net/python/"]}]

(2)xml文件

可扩展标记语言,标准通用标记语言的子集,简称XML。 是一种用于标记电子文件使其具有结构性的标记语言。
一般存储映射关系,在javaweb中有应用web.xml在人工智能中也有应用,比如进行深度学习目标检测用到的数据集,
可以使用xml文件记录一种映射关系对需要训练的数据集进行标注。

代码如下:

 <annotation>
	<folder>VOC2012</folder>
	<filename>2007_000027.jpg</filename>
	<source>
		<database>The VOC2007 Database</database>
		<annotation>PASCAL VOC2007</annotation>
		<image>flickr</image>
	</source>
	<size>
		<width>486</width>
		<height>500</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>person</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>174</xmin>
			<ymin>101</ymin>
			<xmax>349</xmax>
			<ymax>351</ymax>
		</bndbox>
		<part>
			<name>head</name>
			<bndbox>
				<xmin>169</xmin>
				<ymin>104</ymin>
				<xmax>209</xmax>
				<ymax>146</ymax>
			</bndbox>
		</part>
		<part>
			<name>hand</name>
			<bndbox>
				<xmin>278</xmin>
				<ymin>210</ymin>
				<xmax>297</xmax>
				<ymax>233</ymax>
			</bndbox>
		</part>
		<part>
			<name>foot</name>
			<bndbox>
				<xmin>273</xmin>
				<ymin>333</ymin>
				<xmax>297</xmax>
				<ymax>354</ymax>
			</bndbox>
		</part>
		<part>
			<name>foot</name>
			<bndbox>
				<xmin>319</xmin>
				<ymin>307</ymin>
				<xmax>340</xmax>
				<ymax>326</ymax>
			</bndbox>
		</part>
	</object>
</annotation>

(3)gob二进制文件

gob是 Go Binary的简写,是将go语言结构体进行序列化的一种方式,gob文件属于自描述文件,他里面包含所有类型的自描述
进行解码的时候不需要了解文件的内容,在编码解码过程中,零值会被忽略,在解码过程中只有只有匹配名称,和可兼容字段才会被
解码

注意:gob二进制文件比较安全,无法直接打开

②Go语言操作文件的注意点

(1)操作json文件时:

保持字段名大写,可以将对应的字段加入到json文件内

(2)操作xml文件:

结构体字段名后面可以跟类似  `xml:"Name,attr"`、`xml:"Url>Course"`的字符串,用来解释这个字段在xml中的层次结构
除了这两种还有'xml:",chardata"'     将本字段当作字符数据来写
            'xml:",innerxml"'       将本字段按照字面量来写
            'xml:",comment"'        改字段将作为xml注释,写进xml文件

③打开文件的权限

(1)打开文件使用的函数

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
	name为文件名,flag为打开文件权限方式

(2)flag的种类及作用

	O_RDONLY:只读模式打开文件;
	O_WRONLY:只写模式打开文件;
	O_RDWR:读写模式打开文件;
	O_APPEND:写操作时将数据附加到文件尾部(追加);
	O_CREATE:如果不存在将创建一个新文件;
	O_EXCL:和 O_CREATE 配合使用,文件必须不存在,否则返回一个错误;
	O_SYNC:当进行一系列写操作时,每次都要等待上次的 I/O 操作完成再进行;
	O_TRUNC:如果可能,在打开时清空文件。

二、实战使用Go语言操作文件

1.操作json文件

①写文件

代码如下(示例):

package main

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

type Website struct {
    
    
	// 由于权限问题,结构体转json数据格式时会主动频闭掉小写字母开头的数据
	// 结构体转json需要将共享的字段进行大写
	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/"}}}
	// 创建json文件
	// fmt.Println(info)
	fp, err := os.Create("info.json")
	if err != nil {
    
    
		fmt.Println("文件创建失败!", err.Error())
		return
	}
	//延时执行fp.Close()
	defer fp.Close()
	// 使用打开的文件创建json编码器
	encoder := json.NewEncoder(fp)
	//将json数据编码进文件内
	err = encoder.Encode(info)
	if err != nil {
    
    
		fmt.Println("编码错误", err.Error())
	} else {
    
    
		fmt.Println("编码成功!")
	}
	fmt.Println("hello")

}

①读文件

代码如下(示例):

package main

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

type Website struct {
    
    
	Name   string
	Url    string
	Course []string
}

func main() {
    
    
	fp, err := os.Open("info.json")
	if err != nil {
    
    
		fmt.Println("文件打开失败!", err.Error())
		return
	}
	defer fp.Close()
	var info []Website
	// 创建json编码器(将json文件与json对象进行绑定)
	decoder := json.NewDecoder(fp)
	// 从json对象绑定的json文件读取数据
	err = decoder.Decode(&info)
	if err != nil {
    
    
		fmt.Println("解码失败!")
		return
	} else {
    
    
		fmt.Println(info)
	}
	// json数据格式对象返回的是键值对
	for temp, v := range info {
    
    
		fmt.Println(temp, v)
	}

	fmt.Println("123")
}

2.操作xml文件

①写文件

代码如下(示例):

package main

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

/*
	使用go语言进行xml格式文件处理的时候,需要一一对应标签
*/
type Website struct {
    
    
	Name   string `xml:"Name,attr"`
	Url    string //`xml:"Url>Course"`
	Course []string
}

func main() {
    
    
	//实例化对象
	info := []Website{
    
    {
    
    "C语言中文网", "http://c.biancheng.net/golang/", 
		[]string{
    
    "Go语言入门教程", "Golang入门教程"}},
		{
    
    "python程序设计", "http://c.biancheng.net/golangs/", []string{
    
    "人工智能", "网络爬虫"}}}
	fp, err := os.Create("info.xml")
	if err != nil {
    
    
		fmt.Println("出错了!", err.Error())
		return
	}
	defer fp.Close()
	// 序列化到文件
	encoder := xml.NewEncoder(fp)
	err = encoder.Encode(info)
	if err != nil {
    
    
		fmt.Println("编码错误!", err)
	} else {
    
    
		fmt.Println("编码成功!")
	}
	fmt.Println("123")
}

②读文件

代码如下(示例):

package main

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

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

func main() {
    
    
	// 打开一个文件
	fp, err := os.Open("info.xml")
	if err != nil {
    
    
		fmt.Println("打开失败!")
		return
	}
	defer fp.Close()
	info := []Website{
    
    }
	// 加载一个解码器
	decoder := xml.NewDecoder(fp)
	// 值得注意的是,读取xml文件时不是将数据一次读取完,而是每次读取一行组数据
	err = decoder.Decode(&info)
	err = decoder.Decode(&info)

	if err != nil {
    
    
		fmt.Println("解码失败!", err)
	} else {
    
    
		fmt.Println(info)
	}

	fmt.Println("123")
}

3.操作gob文件

①读、写文件

代码如下:

package main

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

/*
	gob是 Go Binary的简写,是将go语言结构体进行序列化的一种方式,gob文件属于自描述文件,他里面包含所有类型的自描述
	进行解码的时候不需要了解文件的内容,在编码解码过程中,零值会被忽略,在解码过程中只有只有匹配名称,和可兼容字段才会被
	解码
*/
func main() {
    
    
	// 创建对象
	info := map[string]string{
    
    
		"name":    "C语言中文网",
		"website": "http://c.biancheng.net/golang/",
	}
	name := "demo.gob"
	fp, err := os.Create(name)
	if err != nil {
    
    
		fmt.Println("创建失败!", err)
		return
	}
	defer fp.Close()
	// 创建编码器,进行编码序列化进文件
	encoder := gob.NewEncoder(fp)
	err = encoder.Encode(info)
	if err != nil {
    
    
		fmt.Println("编码失败!", err)
	} else {
    
    
		fmt.Println("编码成功!")
	}
	// 移动文件描述符,将文件内的光标移到开头
	// 第一个参数是偏移量,第二个参数0代表开头,1代表自身,2代表文件末尾
	fp.Seek(0, 0)
	// 加载一个解码器,对前面创建的文件进行解码
	decoder := gob.NewDecoder(fp)
	var infos map[string]string
	err = decoder.Decode(&infos)
	if err != nil {
    
    
		fmt.Println("error", err)
		fmt.Println("解码失败!")
		return
	} else {
    
    
		fmt.Println("解码成功!")
	}
	// 打印解码出来的数据
	for k := range infos {
    
    
		fmt.Println(k, "对应的值是:", infos[k])
	}

	fmt.Println("123")
}

4.操作普通文本文件

①读、写文件

代码如下:

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func main() {
    
    
	// 打开一个文件
	fp, err := os.Create("text.txt")
	if err != nil {
    
    
		fmt.Println("创建失败!", err)
	}
	defer fp.Close()
	// 写入内容
	writer := bufio.NewWriter(fp)
	// 写入时先将东西写入缓冲区
	writer.WriteString("hello\nTom\n")
	// 想要将缓冲区的数据写入磁盘就需要刷新缓冲区
	writer.Flush()
	// 文件光标移到初始位置
	fp.Seek(0, 0)
	read := bufio.NewReader(fp)
	for {
    
    
		str, err := read.ReadString('\n') //表示一次读一行,其中传进去的是每次中断的符号
		if err == io.EOF {
    
    
			break
		}
		fmt.Print(str)
	}

	fmt.Println("hello")
}

5.操作普通二进制文本文件

①读、写文件

普通二进制文件与gob二进制文件的区别就是普通二进制文件不带自描述,必须人为按照一定的数据格式进行解码
代码如下:

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"os"
)

type WebSite struct {
    
    
	Url int32
}

func main() {
    
    
	fp, err := os.Create("text.bin")
	if err != nil {
    
    
		fmt.Println("创建失败!", err)
	}
	defer fp.Close()
	for i := 0; i < 10; i++ {
    
    
		info := WebSite{
    
    int32(i)}
		var bin_buf bytes.Buffer
		binary.Write(&bin_buf, binary.LittleEndian, info)
		b := bin_buf.Bytes()
		_, err = fp.Write(b)
		if err != nil {
    
    
			fmt.Println("编码失败!", err)
			return
		}
	}
	fmt.Println("123")
}

6.操作压缩文件

①读、写文件

对压缩文件进行层次化的压缩与解压缩
代码如下:

package main

import (
	"archive/zip"
	"bytes"
	"fmt"
	"io"
	"os"
)

func main() {
    
    
	// 创建一个缓冲区用来保存文件内容
	buf := new(bytes.Buffer)
	// 创建一个压缩文件夹
	w := zip.NewWriter(buf)

	// 将文件加入压缩文档
	var file = []struct {
    
    
		Name, Body string
	}{
    
    
		{
    
    "GoLong", "https666"}}

	// 迭代数据,使用数据创建文件
	for _, file := range file {
    
    
		// 在压缩文档内创建文件
		f, err := w.Create(file.Name)
		if err != nil {
    
    
			fmt.Println(err)
		}
		// 在创建好的文件内写数据
		_, err = f.Write([]byte(file.Body))
		if err != nil {
    
    
			fmt.Println(err)
		}
	}
	// 关闭压缩文档
	err := w.Close()
	if err != nil {
    
    
		fmt.Println(err)
	}

	f, err := os.Create("file.zip")
	if err != nil {
    
    
		fmt.Println(err)
	}
	// 将缓冲区的东西写到f文件内
	buf.WriteTo(f)

	// 读取压缩文件中的内容
	// 打开一个zip格式文件
	r, err := zip.OpenReader("file.zip")
	if err != nil {
    
    
		fmt.Println(err)
	}
	defer r.Close()
	// 迭代压缩文件
	for _, f := range r.File {
    
    
		fmt.Printf("文件名:%s\n", f.Name)
		rc, err := f.Open()
		if err != nil {
    
    
			fmt.Println(err)
		}
		_, err = io.CopyN(os.Stdout, rc, int64(f.UncompressedSize64))
		if err != nil {
    
    
			fmt.Println(err.Error())
		}
		rc.Close()
	}
	fmt.Println("123")
}


总结

这里仅仅介绍了各种文件的简单读写操作方式,如果熟练地操作各种文件还需要参考官方文档。


在这里插入图片描述


GO GO GO !

猜你喜欢

转载自blog.csdn.net/apple_51931783/article/details/122506164