Go语言自定义数据文件
来源:云海天教程
时间:2023-02-24 15:48:34 326浏览 收藏
本篇文章给大家分享《Go语言自定义数据文件》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。
对一个程序非常普遍的需求包括维护内部数据结构,为数据交换提供导入导出功能,也支持使用外部工具来处理数据。由于我们这里的关注重点是文件处理,因此我们纯粹只关心如何从程序内部数据结构中读取数据并将其写入标准和自定义格式的文件中,以及如何从标准和自定义格式文件中读取数据并写入程序的内部数据结构中。
本节中,我们会为所有的例子使用相同的数据,以便直接比较不同的文件格式。所有的代码都来自 invoicedate 程序(在 invoicedata 目录中的 invoicedata.go > gob.go、inv.go、jsn.go、txt.go 和 xml.go 等文件中)。大家可以从我的网盘(链接: https://pan.baidu.com/s/1j22QfIScihrauVCVFV6MWw 提取码: ajrk)下载相关的代码。
该程序接受两个文件名作为命令行参数,一个用于读,另一个用于写(它们必须是不同的文件)。程序从第一个文件中读取数据(以其后缀所表示的任何格式),并将数据写入第二个文件(也是以其后缀所表示的任何格式)。
由 invoicedata 程序创建的文件可跨平台使用,也就是说,无论是什么格式,Windows 上创建的文件都可在 Mac OS X 以及 Linux 上读取,反之亦然。Gzip 格式压缩的文件(如 invoices.gob.gz)可以无缝读写。
这些数据由一个 []invoice 组成,也就是说,是一个保存了指向 Invoice 值的指针的切片。每一个发票数据都保存在一个 invoice 类型的值中,同时每一个发票数据都以 []*Item 的形式保存着 0 个或者多个项。
type Invoice struct { Id int Customerld int Raised time.Time Due time.Time Paid bool Note string Items []*Item}type Item struct { Id st ring Price float64 Quantity int Note string}这两个结构体用于保存数据。下表给出了一些非正式的对比,展示了每种格式下读写相同的 50000 份随机发票数据所需的时间,以及以该格式所存储文件的大小。
计时按秒计,并向上舍入到最近的十分之一秒。我们应该把计时结果认为是无绝对单位的,因为不同硬件以及不 同负载情况下该值都不尽相同。大小一栏以千字节(KB)算,该值在所有机器上应该都是相同的。
对于该数据集,虽然未压缩文件的大小千差万别,但压缩文件的大小都惊人的相似。而代码的 函数不包括所有格式通用的代码(例如,那些用于压缩和解压缩以及定义结构体的代码)。
表:各种格式的速度以及大小对比
这些读写时间和文件大小在我们的合理预期范围内,除了纯文本格式的读写异常快之外。这得益于 fmt 包优秀的打印和扫描函数,以及我们设计的易于解析的自定义文本格式。
对于 JSON 和 XML 格式,我们只简单地存储了日期部分而非存储默认的 time.Time 值(一个 ISO-8601 日期/时间字符串),通过牺牲一些速度和增加一些额外代码稍微减小了文件的大小。
例如,如果让JSON代码自己来处理time.Time值,它能够运行得更快,并且其代码行数与 Go语言二进制编码差不多。
对于二进制数据,Go语言的二进制格式是最便于使用的。它非常快且极端紧凑,所需的代码非常少,并且相对容易适应数据的变化。然而,如果我们使用的自定义类型不原生支持 gob 编码,我们必须让该类型满足 gob.Encoder 和 gob. Decoder 接口,这样会导致 gob 格式的 读写相当得慢,并且文件大小也会膨胀。
对于可读的数据,XML 可能是最好使用的格式,特别是作为一种数据交换格式时非常有用。与处理 JSON 格式相比,处理 XML 格式需要更多行代码。这是因为 Go [没有一个 xml.Marshaler 接口,也因为我们这里使用了并行的数据类型 (XMLInvoice 和 XMLItem)来帮助映射 XML 数据和发票数据(invoice 和 Item)。
使用 XML 作为外部存储格式的应用程序可能不需要并行的数据类型或者也不需要 invoicedata 程序这样的 转换,因此就有可能比 invoicedata 例子中所给出的更快,并且所需的代码也更少。
除了读写速度和文件大小以及代码行数之外,还有另一个问题值得考虑:格式的稳健性。例如,如果我们为 Invoice 结构体和 Item 结构体添加了一个字段,那么就必须再改变文件的格式。我们的代码适应读写新格式并继续支持读旧格式的难易程度如何?如果我们为文件格式定义版本,这样的变化就很容易被适应(会以本章一个练习的形式给岀),除了让 JSON 格式同时适应读写新旧格式稍微复杂一点之外。
除了 Invoice 和 Item 结构体之外,所有文件格式都共享以下常量:
const ( fileType = "INVOICES" //用于纯文本格式 magicNumber = 0xl25D // 用于二进制格式 fileVersion = 100 //用于所有的格式 dataFormat = "2006-01-02" //必须总是使用该日期)magicNumber 用于唯一标记发票文件。fileVersion 用于标记发票文件的版本,该标记便于之后修改程序来适应数据格式的改变。dataFormat 稍后介绍,它表 示我们希望数据如何按照可读的格式进行格式化。
同时,我们也创建了一对接口。
type InvoiceMarshaler interface { Marshallnvoices(writer io.Writer, invoices []*Invoice) error}type InvoiceUnmarshaler interface { Unmarshallnvoices(reader io.Reader) ([]*Invoice, error)}这样做的目的是以统一的方式针对特定格式使用 reader 和 writer。例如,下列函数是 invoicedata 程序用来从一个打开的文件中读取发票数据的。
func readinvoices(reader io.Reader, suffix string)([]*Invoice, error) { var unmarshaler InvoicesUnmarshaler switch suffix { case ".gobn: unmarshaler = GobMarshaler{} case H.inv": unmarshaler = InvMarshaler{} case ,f. jsn", H. jsonn: unmarshaler = JSONMarshaler{} case ".txt”: unmarshaler = TxtMarshaler{} case ".xml": unmarshaler = XMLMarshaler{} } if unmarshaler != nil { return unmarshaler.Unmarshallnvoices(reader) } return nil, fmt.Errorf("unrecognized input suffix: %s", suffix)}其中,reader 是任何能够满足 io.Reader 接口的值,例如,一个打开的文件 ( 其类型为 *os . File)> 一个 gzip 解码器 ( 其类型为 *gzip. Reader) 或者一个 string. Readero 字符串 suffix 是文件的后缀名 ( 从 .gz 文件中解压之后)。
在接下来的小节中我们将会看到 GobMarshaler 和 InvMarshaler 等自定义的类型,它们提供了 MarshmlTnvoices() 和 Unmarshallnvoices() 方法 (因此满足 InvoicesMarshaler 和 InvoicesUnmarshaler 接口)。
理论要掌握,实操不能落!以上关于《Go语言自定义数据文件》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
-
225 收藏
-
389 收藏
-
250 收藏
-
137 收藏
-
190 收藏
-
113 收藏
-
140 收藏
-
277 收藏
-
186 收藏
-
346 收藏
-
286 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习