C# 中的简洁二进制对象表示 (CBOR)






4.83/5 (10投票s)
C# 实现的简洁二进制对象表示,属于公共领域
请参阅“如何安装”以了解如何安装此 .NET 包。
引言
C# 实现的简洁二进制对象表示,这是一种在 RFC 7049 中定义的一般用途的二进制数据格式。根据该 RFC,CBOR 的数据模型“是 JSON 数据模型的扩展版本”,支持比 JSON 多得多的数据类型。“CBOR 的灵感来自 MessagePack”,但“并非旨在作为 MessagePack 的版本或替代品。”
此实现由 Peter O. 编写,并根据 CC0 声明 释放到公共领域。
此实现也兼作 JSON 的读取器和写入器,并且可以将数据从 JSON 转换为 CBOR,然后再转回。
最后,此实现支持任意精度的二进制和十进制浮点数以及具有任意精度组件的理数。
源代码可在 项目页面 中找到。
如何安装
从版本 0.21.0 开始,C# 实现可在 NuGet 包库中找到,名称为 PeterO.Cbor。要将此库作为 NuGet 包安装,请在 NuGet 包管理器控制台中输入 Install-Package PeterO.Cbor
。
文档
此库定义了一个名为 CBORObject 的类,它允许您将 CBOR 对象读写到数据流和字节数组,并将 JSON 文本转换为 CBOR 对象,然后再转回。
请参阅 C# (.NET) API 文档。
C# 实现被设计为可移植类库。
其他网站
- CodePlex: https://peterocbor.codeplex.com/
- Code Project: https://codeproject.org.cn/Tips/897294/Concise-Binary-Object-Representation-CBOR-in-Cshar
- SourceForge: https://sourceforge.net/p/petero-cbor
示例
创建映射并将该映射转换为 CBOR 字节和 JSON 字符串
<code>// The following creates a CBOR map and adds
// several kinds of objects to it
var cbor = CBORObject.NewMap()
.Add("item", "any string")
.Add("number", 42)
.Add("map", CBORObject.NewMap().Add("number", 42))
.Add("array", CBORObject.NewArray().Add(999f).Add("xyz"))
.Add("bytes", new byte[] { 0, 1, 2 });
// The following converts the map to CBOR
byte[] bytes = cbor.EncodeToBytes();
// The following converts the map to JSON
string json = cbor.ToJSONString();
Console.WriteLine(json);
从文件读取数据 (C#)。请注意,所有用于读写文件的示例都假定该平台支持文件 I/O;可移植类库不作此假设。
<code> // Read all the bytes from a file and decode the CBOR object
// from it. However, there are two disadvantages to this approach:
// 1. The byte array might be very huge, so a lot of memory to store
// the array may be needed.
// 2. The decoding will succeed only if the entire array,
// not just the start of the array, consists of a CBOR object.
var cbor = CBORObject.DecodeFromBytes(File.ReadAllBytes("object.cbor"));
从文件读取数据的另一个例子
<code> // C#
// Open the file stream
using (var stream = new FileStream("object.cbor", FileMode.Open)) {
// Read the CBOR object from the stream
var cbor = CBORObject.Read(stream);
// At this point, the object is read, but the file stream might
// not have ended yet. Here, the code may choose to read another
// CBOR object, check for the end of the stream, or just ignore the
// rest of the file. The following is an example of checking for the
// end of the stream.
if (stream.Position != stream.Length) {
// The end of the stream wasn't reached yet.
} else {
// The end of the stream was reached.
}
}
如果字节数组包含多个 CBOR 对象,则应将字节数组包装在 MemoryStream 中,并使用该流读取这些对象,因为 DecodeFromBytes 假定数组仅包含一个 CBOR 对象。这是一个例子。
<code> // C#
// Create a memory stream with a view of the byte array
using (var stream = new MemoryStream(byteArray)) {
// Read the CBOR object from the stream
var cbor = CBORObject.Read(stream);
// The rest of the example follows the one given above.
}
将 CBOR 数据写入文件 (C#)
<code>// This example assumes that the variable "cbor" refers
// to a CBORObject object.
using (var stream = new FileStream("object.cbor", FileMode.Create)) {
cbor.WriteTo(stream);
}
将多个对象写入文件,包括任意对象
<code>// C#
// This example writes different kinds of objects in CBOR
// format to the same file.
using (var stream = new FileStream("object.cbor", FileMode.Create)) {
CBORObject.Write(true, stream);
CBORObject.Write(422.5, stream);
CBORObject.Write("some string", stream);
CBORObject.Write(CBORObject.Undefined, stream);
CBORObject.NewArray().Add(42).WriteTo(stream);
}
从文件读取 JSON
<code> // Open the file stream
using (var stream = new FileStream("object.json", FileMode.Open)) {
// Read the JSON object from the stream
// as a CBOR object
var cbor = CBORObject.ReadJSON(stream);
}
将 CBOR 对象作为 JSON 写入
<code>// This example assumes that the variable "cbor" refers
// to a CBORObject object.
// NOTE: Specifying Encoding.UTF8 as the third parameter
// would add a byte order mark to the beginning of the text,
// but conforming JSON implementations are forbidden from
// adding it this way in JSON texts they generate.
File.WriteAllText(
"object.json",
cbor.ToJSONString(),
new System.Text.Encoding.UTF8Encoding(false));
// This is an alternative way to write the CBOR object
// and is now supported in version 1.2.
using (var stream = new FileStream("object2.json", FileMode.Create)) {
// Write the CBOR object as JSON; here, a byte order
// mark won't be added
cbor.WriteJSONTo(stream);
}
// Version 1.2 now supports a third way to write
// objects to JSON: the CBORObject.WriteJSON method
using (var stream = new FileStream("object3.json", FileMode.Create)) {
CBORObject.WriteJSON("some string", stream);
}
using (var stream = new FileStream("object4.json", FileMode.Create)) {
CBORObject.WriteJSON(cbor, stream);
}
using (var stream = new FileStream("object5.json", FileMode.Create)) {
CBORObject.WriteJSON(true, stream);
}
using (var stream = new FileStream("object6.json", FileMode.Create)) {
CBORObject.WriteJSON(42, stream);
}
注意:本节中的所有代码示例均已发布到公共领域,如 http://creativecommons.org/publicdomain/zero/1.0/ 中所述。
演示
转到 https://github.com/peteroupc/Calculator 获取 CBOR 库的演示源代码,该演示以计算器的形式呈现。
关于
由 Peter O. 于 2013-2017 年编写。
任何版权均奉献给公共领域。 http://creativecommons.org/publicdomain/zero/1.0/
如果您喜欢这个,您应该向 Peter O. 捐款,网址为:http://peteroupc.github.io/CBOR/
说明
以下是对 RFC 7049 的一些说明。
- 第 2.4.2 节未指定如果大数的字节字符串长度为 0 会发生什么情况。此实现将长度为 0 的正大数视为值为 0,将长度为 0 的负大数视为值为 -1。
- 第 2.4.1 节指定了自 1970 年开始的秒数。它基于“自纪元以来的秒数”的 POSIX 定义,RFC 将其引用为规范性参考。此定义不计算闰秒。当此实现支持日期转换时,它也不会计算闰秒。此实现将无穷大和 NaN 的值视为无效。
- 对于标签 32,此实现除了 URI 之外,还接受有效的国际化资源标识符 (IRI) 字符串。 IRI 类似于 URI,只是它们也允许非 ASCII 字符。
发布说明
版本 3.0.2
修复了加载库时未预见到的问题
版本 3.0.0
版本 3.0.0
- 从 .NET 可移植版移至 .NET Standard 1.0。
- 弃用了 PeterO 命名空间中的任意精度类;改为使用 "PeterO.Numbers" 库和命名空间中的类。特别是,以前使用旧类的那些方法已被弃用,并且经常被使用较新类的版本替换。
- 略微更改 JSON 输出行为,包括保留负零
- 在此版本中更改了哈希码计算
- 弃用了 CBORObject 中的 OutermostTag,改为使用 MostOuterTag
- 弃用了 CBORObject 中的 InnermostTag,改为使用 MostInnerTag
- Bug 修复
有关旧版本的发行说明,请参阅 History.md。