go语言文件处理-01

news/2024/4/25 21:11:05/文章来源:https://www.cnblogs.com/mayanan/p/16628406.html

go语言json文件的读写操作

JSON 是一种使用 UTF-8 编码的纯文本格式,采用完全独立于语言的文本格式,由于写起来比 XML 格式方便,并且更为紧凑,同时所需的处理时间也更少,致使 JSON 格式越来越流行,特别是在通过网络连接传送数据方面。

开发人员可以使用 JSON 传输简单的字符串、数字、布尔值,也可以传输一个数组或者一个更复杂的复合结构。在 Web 开发领域中,JSON 被广泛应用于 Web 服务端程序和客户端之间的数据通信。

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

写json文件

使用go语言创建一个json文件非常方便,示例代码如下:

type Website struct {Name string `xml:"name,attr"`Url stringCourse []string
}
func main() {info := []Website{{"golang", "https://www.golang.com", []string{"go", "lang"}},{"python", "https://www.python.com", []string{"py", "thon"}},}filePtr, err := os.Create("info.json")defer func() {if err = filePtr.Close(); err != nil {fmt.Println("创建json文件失败", err.Error())}}()if err != nil {fmt.Println(err.Error())return}// 创建json编码器encoder := json.NewEncoder(filePtr)err = encoder.Encode(info)if err != nil {fmt.Println("编码错误", err.Error())}else {fmt.Println("编码成功")}
}
读取json文件

读取json数据与写json数据一样简单:

func main() {// 读取json文件数据filePtr, err := os.Open("./info.json")if err != nil {fmt.Println(err.Error())return}defer func() {if err = filePtr.Close(); err != nil {fmt.Println(err.Error())}}()var info []Website// 创建json解码器decoder := json.NewDecoder(filePtr)if err = decoder.Decode(&info); err != nil {fmt.Println(err.Error())}else{fmt.Println(info)}
}

顺便提一下,还有一种叫做 BSON (Binary JSON) 的格式与 JSON 非常类似,与 JSON 相比,BSON 着眼于提高存储和扫描效率。BSON 文档中的大型元素以长度字段为前缀以便于扫描。在某些情况下,由于长度前缀和显式数组索引的存在,BSON 使用的空间会多于 JSON。

go语言xml文件的读写操作

XML(extensible Markup Language)格式被广泛用作一种数据交换格式,并且自成一种文件格式。与上一节介绍的 JSON 相比 XML 要复杂得多,而且手动写起来相对乏味得多。

在 JSON 还未像现在这么广泛使用时,XML 的使用相当广泛。XML 作为一种数据交换和信息传递的格式,使用还是很广泛的,现在很多开放平台接口,基本都会支持 XML 格式。

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

写xml文件

使用encoding/xml包可以很方便的将xml数据存储到文件中:

type Website struct {Name string `xml:"name,attr"`Url stringCourse []string
}
func main() {info := Website{"golang", "https://www.golang.com", []string{"go", "lang"}}// 创建xml文件filePtr, err := os.Create("./info.xml")if err != nil {fmt.Println(err.Error())return}defer func() {if err = filePtr.Close(); err != nil {fmt.Println(err)}}()// 创建xml编码器encoder := xml.NewEncoder(filePtr)if err = encoder.Encode(info); err != nil {fmt.Println("编码失败", err.Error())}else{fmt.Println("编码成功")}
}
读取xml文件

读 XML 文件比写 XML 文件稍微复杂,特别是在必须处理一些我们自定义字段的时候(例如日期)。但是,如果我们使用合理的打上 XML 标签的结构体,就不会复杂。示例代码如下:

type Website struct {Name string `xml:"name,attr"`Url stringCourse []string
}
func main() {filePtr, err := os.Open("./info.xml")if err != nil {fmt.Println(err.Error())return}defer func() {if err = filePtr.Close(); err != nil {fmt.Println(err.Error())}}()var website Websitedecoder := xml.NewDecoder(filePtr)if err = decoder.Decode(&website); err != nil {fmt.Println(err.Error())}else{fmt.Println(website)}
}

正如写 XML 时一样,我们无需关心对所读取的 XML 数据进行转义,xml.NewDecoder.Decode() 函数会自动处理这些。

xml 包还支持更为复杂的标签,包括嵌套。 例如标签名为 'xml:"Books>Author"' 产生的是content这样的 XML 内容。同时除了 ‘xml:”, attr”‘ 之外,该包还支持 ‘xml:”,chardata”‘ 这样的标签表示将该字段当做字符数据来写,支持 ‘xml:”,innerxml”‘ 这样的标签表示按照字面量来写该字段,以及 ‘xml:”,comment”‘ 这样的标签表示将该字段当做 XML 注释。因此,通过使用标签化的结构体,我们可以充分利用好这些方便的编码解码函数,同时合理控制如何读写 XML 数据。

go语言使用Gob传输数据

为了让某个数据结构能够在网络上传输或能够保存至文件,它必须被编码然后再解码。当然已经有许多可用的编码方式了,比如 JSON、XML、Google 的 protocol buffers 等等。而现在又多了一种,由Go语言 encoding/gob 包提供的方式。

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

Gob 和 JSON 的 pack 之类的方法一样,由发送端使用 Encoder 对数据结构进行编码。在接收端收到消息之后,接收端使用 Decoder 将序列化的数据变化成本地变量。

Go语言可以通过 JSON 或 Gob 来序列化 struct 对象,虽然 JSON 的序列化更为通用,但利用 Gob 编码可以实现 JSON 所不能支持的 struct 的方法序列化,利用 Gob 包序列化 struct 保存到本地也十分简单。

Gob 不是可外部定义、语言无关的编码方式,它的首选的是二进制格式,而不是像 JSON 或 XML 那样的文本格式。Gob 并不是一种不同于 Go 的语言,而是在编码和解码过程中用到了 Go 的反射。

Gob通常用于远程方法调用参数和结果的传输,以及应用程序和机器之间的数据传输。它和 JSON 或 XML 有什么不同呢?Gob 特定的用于纯 Go 的环境中,例如两个用Go语言写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。

Gob 文件或流是完全自描述的,它里面包含的所有类型都有一个对应的描述,并且都是可以用Go语言解码,而不需要了解文件的内容。

只有可导出的字段会被编码,零值会被忽略。在解码结构体的时候,只有同时匹配名称和可兼容类型的字段才会被解码。当源数据类型增加新字段后,Gob 解码客户端仍然可以以这种方式正常工作。解码客户端会继续识别以前存在的字段,并且还提供了很大的灵活性,比如在发送者看来,整数被编码成没有固定长度的可变长度,而忽略具体的 Go 类型。

加入有这样一个结构体T:

type T struct { X, Y, Z int }
var t = T{X: 7, Y: 0, Z: 8}

而在接收时可以用一个结构体U类型的变量u来接收这个值:

type U struct { X, Y *int8 }
var u U

接收时,X 的值是 7,Y 的值是 0(Y 的值并没有从 t 中传递过来,因为它是零值)和 JSON 的使用方式一样,Gob 使用通用的 io.Writer 接口,通过 NewEncoder() 函数创建 Encoder 对象并调用 Encode(),相反的过程使用通用的 io.Reader 接口,通过 NewDecoder() 函数创建 Decoder 对象并调用 Decode 。

创建gob文件

下面通过简单的示例程序来演示Go语言是如何创建 gob 文件的,代码如下所示:

func main() {info := map[string]string{"name": "golang","website": "https://www.golang.com",}filePtr, err := os.OpenFile("demo.gob", os.O_RDWR|os.O_CREATE, 0777)if err != nil {fmt.Println(err)}defer filePtr.Close()// 创建gob编码器encoder := gob.NewEncoder(filePtr)if err = encoder.Encode(&info); err != nil {fmt.Println(err.Error())}
}
读取gob文件

读取gob文件与创建gob文件同样简单:

func main() {filePtr, _ := os.OpenFile("./demo.gob", os.O_RDONLY, 0755)defer filePtr.Close()decoder := gob.NewDecoder(filePtr)var m map[string]string_ = decoder.Decode(&m)fmt.Println(m, m["name"])
}

go语言纯文本文件的读写操作

Go语言提供了很多文件操作的支持,在不同场景下,有对应的处理方式,本节我们来介绍一下文本文件的读写操作。

写纯文本文件

由于go语言fmt包中打印函数强大而灵活。写纯文本数据非常简单而直接:

func main() {filePtr, err := os.OpenFile("./out.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)if err != nil {fmt.Println(err)return}defer filePtr.Close()str := "hello world, 你好 世界\n"// 写入时,使用带缓存的*Writerwriter := bufio.NewWriter(filePtr)for i := 0; i < 3; i++ {writer.WriteString(str)}// 因为writer是带缓存的,因此在调用WriteString方法时,内容是先写入缓存的// 所以要调用Flush方法,将缓存的数据真正写入到文件中writer.Flush()
}
读纯文本文件

打开并读取一个纯文本格式的数据跟写入纯文本格式数据一样简单。要解析文本来重建原始数据可能稍微复杂,这需根据格式的复杂性而定。

func main() {file, err := os.Open("./out.txt")if err != nil {fmt.Println(err.Error())return}defer file.Close()// 创建一个带缓存的*Readerreader := bufio.NewReader(file)for {str, err := reader.ReadString('\n')if err == io.EOF {break}fmt.Printf(str)}fmt.Println("文件读取结束")
}

go语言二进制文件的读写操作

Go语言的二进制(gob)格式是一个自描述的二进制序列。从其内部表示来看,Go语言的二进制格式由一个 0 块或者更多块的序列组成,其中的每一块都包含一个字节数,一个由 0 个或者多个 typeId-typeSpecification 对组成的序列,以及一个 typeId-value 对。

如果 typeId-value 对的 typeId 是预先定义好的(例如 bool、int 和 string 等),则这些 typeId-typeSpecification 对可以省略。否则就用类型对来描述一个自定义类型(如一个自定义的结构体)。类型对和值对之间的 typeId 没有区别。

正如我们将看到的,我们无需了解其内部结构就可以使用 gob 格式, 因为 encoding/gob 包会在幕后为我们打理好一切底层细节。

Go语言中的 encoding/gob 包也提供了与 encoding/json 包一样的编码解码功能,并且容易使用。通常而言如果对肉眼可读性不做要求,gob 格式是Go语言上用于文件存储和网络传输最为方便的格式。

写go语言二进制文件

下面通过一个简单的示例来演示一下Go语言是如何生成一个二进制文件的,代码如下所示:

func main() {str := "这是一个二进制文件的内容 hello world 20220829"// 以写入的方式打开文件filePtr, err := os.OpenFile("bytes.gob", os.O_WRONLY|os.O_CREATE, 0644)if err != nil {fmt.Println(err)return}defer filePtr.Close()// 生成gob格式的编码器encoder := gob.NewEncoder(filePtr)// 将内容通过编码器写入到文件中_ = encoder.Encode(str)
}
读go语言二进制文件

读gob数据和写一样简单,代码如下:

func main() {filePtr, err := os.Open("./bytes.gob")if err != nil {fmt.Println(err)return}defer filePtr.Close()decoder := gob.NewDecoder(filePtr)var ret stringif err = decoder.Decode(&ret); err != nil {fmt.Println(err)}else{fmt.Println(ret)}
}

go语言自定义二进制文件的读写操作

虽然Go语言的 encoding/gob 包非常易用,而且使用时所需代码量也非常少,但是我们仍有可能需要创建自定义的二进制格式。自定义的二进制格式有可能做到最紧凑的数据表示,并且读写速度可以非常快。

不过,在实际使用中,我们发现以Go语言二进制格式的读写通常比自定义格式要快非常多,而且创建的文件也不会大很多。但如果我们必须通过满足 gob.GobEncoder 和 gob.GobDecoder 接口来处理一些不可被 gob 编码的数据,这些优势就有可能会失去。

在有些情况下我们可能需要与一些使用自定义二进制格式的软件交互,因此了解如何处理二进制文件就非常有用。

写自定义二进制文件

Go语言的 encoding/binary 包中的 binary.Write() 函数使得以二进制格式写数据非常简单,函数原型如下:
func Write(w io.Writer, order ByteOrder, data interface{}) error
Write 函数可以将参数 data 的 binary 编码格式写入参数 w 中,参数 data 必须是定长值、定长值的切片、定长值的指针。参数 order 指定写入数据的字节序,写入结构体时,名字中有_的字段会置为 0。

下面通过一个简单的示例程序来演示一下 Write 函数的使用,示例代码如下:

type Website struct {Url int32
}
func main() {file, err := os.Create("byte.bin")if err != nil {fmt.Println(err)return}defer file.Close()for i := 0; i < 10; i++ {info := Website{int32(i)}var binBuffer bytes.Buffererr = binary.Write(&binBuffer, binary.LittleEndian, &info)if err != nil {fmt.Println(err)continue}byteSlice := binBuffer.Bytes()_, _ = file.Write(byteSlice)}
}
读自定义二进制文件

读取自定义的二进制数据与写自定义二进制数据一样简单。我们无需解析这类数据,只需使用与写数据时相同的字节顺序将数据读进相同类型的值中。

示例代码如下:

type Website struct {Url int32
}
func main() {file, err := os.Open("byte.bin")if err != nil {fmt.Println(err)return}defer file.Close()for i := 0; i < 10; i++ {b := make([]byte, 4)_, err = file.Read(b)if err != nil {fmt.Println(err)continue}buffer := bytes.NewBuffer(b)w := Website{}err = binary.Read(buffer, binary.LittleEndian, &w)if err != nil {fmt.Println(err)}fmt.Printf("第 %d 个值为 %+v:\n", i, w)}
}

至此,我们完成了对自定义二进制数据的读和写操作。只要小心选择表示长度的整数符号和大小,并将该长度值写在变长值(如切片)的内容之前,那么使用二进制数据进行工作并不难。

Go语言对二进制文件的支持还包括随机访问。这种情况下,我们必须使用 os.OpenFile() 函数来打开文件(而非 os.Open()),并给它传入合理的权限标志和模式(例如 os.O_RDWR 表示可读写)参数。

然后,就可以使用 os.File.Seek() 方法来在文件中定位并读写,或者使用 os.File.ReadAt() 和 os.File.WriteAt() 方法来从特定的字节偏移中读取或者写入数据。

Go语言还提供了其他常用的方法,包括 os.File.Stat() 方法,它返回的 os.FileInfo 包含了文件大小、权限以及日期时间等细节信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_2902.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux

1、关机命令命令 说明sync 将数据由内存同步到硬盘中shutdown 关机shutdown -h 10 10分钟后关机shutdown -h now 立马关机shutdown -h 20:25 指定时间关机shutdown -h +10 10分钟后关机shutdown -r now 系统立马重启shutdown -r +10 10分钟后重启reboot 重启,等于shutdown -r …

线性布局LinearLayout

线性布局中的下级视图有两种排列方式当orientation属性为horizontal时,线性布局中的下级视图在水平方向上从左往右排列 当orientation属性为vetical时,线性布局中的下级视图在垂直方向上从上往下排列线性布局的权重 概念:线性布局的权重,用来表示线性布局中各视图所占比例大…

NC50439 tokitsukaze and Soldier

在一个游戏中,tokitsukaze需要在n个士兵中选出一些士兵组成一个团去打副本。 第i个士兵的战力为v[i],团的战力是团内所有士兵的战力之和。 但是这些士兵有特殊的要求:如果选了第i个士兵,这个士兵希望团的人数不超过s[i]。(如果不选第i个士兵,就没有这个限制。) tokitsukaz…

Dos命令

打开cmdwin+r ->cmd 以管理员身份运行win->windows系统->命令提示符->右键->更多->以管理员身份运行 常用的Dos命令 盘符切换 输入D: 切到D盘 查看当前目录下的所有文件 dir 切换目录 cd (change directory) cd msicheng 从Users文件夹进入其子文件夹msiche…

个人网盘搭建——搭建Cloudreve并对接onedrive

前言 搭建这个主要是为了方便自己备份,顺便可以水一下文章(bushi) 其次是自己有好几个微软的全局账号吃灰,还是想稍微利用一下的,如果有人要子号可以来联系哦,好心的我应该会给你的吧 由于个人使用,不会介绍很难的安装方法。下面会介绍宝塔简单快速的安装方法。后续也许…

Spring学习笔记(三)——Spring依赖注入

1.Spring Bean属性注入的几种方式 1.1构造函数注入 使用构造函数实现属性注入大致步骤如下:在 Bean 中添加一个有参构造函数,构造函数内的每一个参数代表一个需要注入的属性; 在 Spring 的 XML 配置文件中,通过 <beans> 及其子元素 <bean> 对 Bean 进行定义; …

动态规划算法(背包问题)

1.应用场景-背包问题 背包问题:有一个背包,容量为4磅 ,现有如下物品1)要求达到的目标为装入的背包的总价值最大,并且重量不超出 2)要求装入的物品不能重复 2.动态规划算法介绍 1)动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步…

开启apache服务器gzip压缩

开启apache服务器gzip压缩-百度经验 https://jingyan.baidu.com/article/db55b609a7bc234ba20a2f7e.html 从服务端优化来说,通过对服务端做压缩配置可以大大减小文本文件的体积,从而使加载文本的速度成倍的加快。目前比较通用的压缩方法是启用gzip压缩。它会把浏览器请求的页…

Linux修改主机静态IP

通过VIM编辑器打开主机配置文件夹vim /etc/sysconfig/network-scripts/ifcfg-ens33修改IP地址为静态地址BOOTPROTO="static"添加静态IP地址和网关IP 地址 IPADDR=192.168.244.100 网关 GATEWAY=192.168.244.2 域名解析器 DNS1=192.168.244.2网络重启service network …

点击按钮收藏

分析 后台代码RouteServlet类:/*** 添加收藏* @param request* @param response* @throws ServletException* @throws IOException*/public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1、获取线…

前端5JQ

js获取用户输入 JS类属性操作 JS样式操作 事件 JS事件案例 JQuery类库 JQuery基本使用 基本筛选器(了解) 表单筛选器Js获取用户输入 普通数据(输入,选择) ​ 标签对象.value 获取文件数据的时候: 标签对象.value只能获取到文件路径,而标签对象.files结果是一个数组,可以通…

前端Day10

视口(viewport):浏览器显示页面内容的屏幕区域。分为布局视口、视觉视口、理想视口。 布局视口: 视觉视口: 理想视口: meta视口标签: width=device-width:布局视口宽度为当前设备宽度* user-scalable=no:不允许用户缩放 二倍图: 1.物理像素比: ①物理像素:即分辨…

分布式系统的session共享问题

目前大多数大型网站的服务器都采用了分布式服务集群的部署方式。所谓集群,就是让一组计算机服务器协同工作,解决大并发,大数据量瓶颈问题。但是在服务集群中,session共享往往是一个比较头疼的问题。因为session是在服务器端保存的,如果用户跳转到其他服务器的话,session就…

网络network

网络network 基础network模型 OSI七层模型,一层一层封装数据帧(添加报文头),传过去之后再一层一层解封装(解封装掉报文头) 应用层:应用软件层面业务端口,例如http/https,ftp,sftp,smtp(25),除了在四层TCP IP+端口号的方式进行外,还需要检查http/https的url,cook…

python中的多线程与多进程

线程概念: 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一…

从设计到代码(第 3 天)

从设计到代码(第 3 天) 我最近正在开发一门课程,名为 三周内完成三个网页设计 .最初它是一个为期 3 周的研讨会材料,旨在成为一个包含许多实践的动手密集型研讨会。主要目标是教没有太多开发经验的人使用 HTML 和 CSS 来重现专业的设计模型——这就是为什么它被称为从设计到…

力扣507(java)-完美数(简单)

题目: 对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。 给定一个 整数 n, 如果是完美数,返回 true;否则返回 false。示例 1: 输入:num = 28输出:true解释:28 = 1 + 2 + 4 + 7 + 141, 2, 4, 7和 14 是 28 的所有正因子。示例 …

仅Intel电脑可用:设计2D/3D文档绘图Autodesk AutoCAD 2021

Autodesk AutoCAD 2021是Mac上的二维和三维CAD设计软件,用于产品衍生式设计,创建设计方案,三维模型参数化,建模部件组织,创建制作清晰工程图,设计自动化配置等,AutoCAD 2021增强了针对草图的命令设计,简化流程,改进各种性能,转化探索更强大的设计。​编辑切换为居中 …

Echarts与ajax数据的动态交互

初学Echarts,Echarts的官网示例中配置项的数据需要用到js数组来传递数据,所以当我们从后端查询到数据后,往往需要通过ajax来进行数据交互。 这是官方示例的配置项。<script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = ech…

Openwrt 纯ipv6环境管理和上网

防火墙打开远程管理端口 添加端口如22或者使用ipv6端口转发到ipv4 使用socat opkg install socat图形化界面: drophair / luci-app-socatg wget -P /tmp https://github.com/big-tooth/luci-app-socatg/releases/download/v1.1/luci-app-socatg_1.1-1_all.ipk opkg install /tm…