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 份随机发票数据所需的时间,以及以该格式所存储文件的大小。| 后缀 | 读取 | 写入 | 大小(KiB) | 读/写LOC | 格式 |
|---|---|---|---|---|---|
| .gob | 0.3 | 0.2 | 7948 | 21 + 11 =32 | Go二进制 |
| .gob.gz | 0.5 | 1.5 | 2589 | ||
| jsn | 4.5 | 2.2 | 16283 | 32+17 = 49 | JSON |
| .jsn.gz | 4.5 | 3.4 | 2678 | ||
| .xml | 6.7 | 1.2 | 18917 | 45 + 30 = 75 | XML |
| .xml.gz | 6.9 | 2.7 | 2730 | ||
| ..txt | 1.9 | 1.0 | 12375 | 86 + 53 = 139 | 纯文本(UTF-8) |
| .txt.gz | 2.2 | 2.2 | 2514 | ||
| .inv | 1.7 | 3.5 | 7250 | 128 + 87 = 215 | 自定义二进制 |
| .inv.gz | 1.6 | 2.6 | 2400 |
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 文件中解压之后)。
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有