- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 MessagePack
保存多个结构列表,因为我读到它的性能优于 BinaryFormatter
序列化。
我想要做的是接收实时时间序列数据并定期将其定期保存(附加)到磁盘上,例如,如果列表的元素数为 100。我的问题是:
1)在这种情况下,序列化结构列表并将其异步保存到磁盘会更好吗?
2) 如何使用 MessagePack 将其简单地保存到磁盘?
public struct struct_realTime
{
public int indexNum { get; set; }
public string currentTime { get; set; }
public string currentType { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<struct_realTime> list_temp = new List<struct_realTime>(100000);
for (int num=0; num < 100000; num++)
{
list_temp.Add(new struct_realTime
{
indexNum = 1,
currentTime = "time",
currentType = "type",
});
}
string filename = "file.bin";
using (var fileStream = new FileStream(filename, FileMode.Append, FileAccess.Write))
{
byte[] bytes = MessagePackSerializer.Serialize(list_temp);
Console.WriteLine(MessagePackSerializer.ToJson(bytes));
}
}
}
file.bin
并打印出 100000 个结构,但文件为 0 字节。
BinaryFormatter
,我这样做:
using (var fileStream = new FileStream("file.bin", FileMode.Append))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fileStream, list_temp);
}
最佳答案
您要做的是附加使用 List<struct_realTime>
序列化的对象(此处为 MessagePackSerializer
)到一个包含类似对象的已经序列化序列的文件,与 BinaryFormatter
可能的方式相同, protobuf-net或 Json.NET .稍后,您可能希望能够将整个序列反序列化为相同类型的对象列表或数组。
您的代码存在三个问题,两个简单问题和一个基本问题。
简单的问题如下:
fileStream
.相反,请执行以下操作:// Append each list_temp sequentially
using (var fileStream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
MessagePackSerializer.Serialize(fileStream, list_temp);
}
struct_realTime
与 [MessagePackObject]
attributes .这可以实现,例如如下:[MessagePackObject]
public struct struct_realTime
{
[Key(0)]
public int indexNum { get; set; }
[Key(1)]
public string currentTime { get; set; }
[Key(2)]
public string currentType { get; set; }
}
list_temp
到一个文件...但你以后将无法读取它们!那是因为
MessagePackSerializer
反序列化根对象时似乎读取了整个文件,跳过了文件中附加的任何其他数据。因此,如下代码将失败,因为从文件中只读取了一个对象:
List<List<struct_realTime>> allItemsInFile = new List<List<struct_realTime>>();
using (var fileStream = File.OpenRead(filename))
{
while (fileStream.Position < fileStream.Length)
{
allItemsInFile.Add(MessagePackSerializer.Deserialize<List<struct_realTime>>(fileStream));
}
}
Assert.IsTrue(allItemsInFile.Count == expectedNumberOfRootItemsInFile);
List<List<struct_realTime>> allItemsInFile;
using (var fileStream = File.OpenRead(filename))
{
allItemsInFile = MessagePackSerializer.Deserialize<List<List<struct_realTime>>>(fileStream);
}
Assert.IsTrue(allItemsInFile.Count == expectedNumberOfRootItemsInFile);
MessagePackSerializer
似乎缺乏从流中反序列化多个根对象的能力,您有什么选择?首先,您可以反序列化
List<List<struct_realTime>>
,追加到它,然后将整个东西序列化回文件。大概出于性能原因,您不想这样做。
array 32
format header ,然后查找文件末尾并使用
MessagePackSerializer
序列化和附加新项目。以下扩展方法可以完成这项工作:
public static class MessagePackExtensions
{
const byte Array32 = 0xdd;
const int Array32HeaderLength = 5;
public static void AppendToFile<T>(Stream stream, T item)
{
if (stream == null)
throw new ArgumentNullException(nameof(stream));
if (!stream.CanSeek)
throw new ArgumentException("!stream.CanSeek");
stream.Position = 0;
var buffer = new byte[Array32HeaderLength];
var read = stream.Read(buffer, 0, Array32HeaderLength);
stream.Position = 0;
if (read == 0)
{
FormatArray32Header(buffer, 1);
stream.Write(buffer, 0, Array32HeaderLength);
}
else
{
var count = ParseArray32Header(buffer, read);
FormatArray32Header(buffer, count + 1);
stream.Write(buffer, 0, Array32HeaderLength);
}
stream.Position = stream.Length;
MessagePackSerializer.Serialize(stream, item);
}
static void FormatArray32Header(byte [] buffer, uint value)
{
buffer[0] = Array32;
buffer[1] = unchecked((byte)(value >> 24));
buffer[2] = unchecked((byte)(value >> 16));
buffer[3] = unchecked((byte)(value >> 8));
buffer[4] = unchecked((byte)value);
}
static uint ParseArray32Header(byte [] buffer, int readCount)
{
if (readCount < 5 || buffer[0] != Array32)
throw new ArgumentException("Stream was not positioned on an Array32 header.");
int i = 1;
//https://stackoverflow.com/questions/8241060/how-to-get-little-endian-data-from-big-endian-in-c-sharp-using-bitconverter-toin
//https://stackoverflow.com/a/8241127 by https://stackoverflow.com/users/23354/marc-gravell
var value = unchecked((uint)((buffer[i++] << 24) | (buffer[i++] << 16) | (buffer[i++] << 8) | buffer[i++]));
return value;
}
}
list_temp
如下:
// Append each entry sequentially
using (var fileStream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
MessagePackExtensions.AppendToFile(fileStream, list_temp);
}
List<List<struct_realTime>> allItemsInFile;
using (var fileStream = File.OpenRead(filename))
{
allItemsInFile = MessagePackSerializer.Deserialize<List<List<struct_realTime>>>(fileStream);
}
fixarray
存储一个长度最多为 15 个元素的数组。 array 16
存储一个长度最多为 (2^16)-1 个元素的数组。 array 32
存储一个长度最多为 (2^32)-1 个元素的数组。 array 32
当新大小大于
fixarray
的容量时,无需重新格式化整个阵列或
array 16
.
MessagePackSerializer
但是,将始终写入最紧凑的格式,因此附加到先前由
MessagePackSerializer
序列化的集合中不保证工作。
MessagePackSerializer
的属性来标记您的类型。 . 关于c# - 如何在 C# 中保存并附加到序列化的 MessagePack 二进制文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58780225/
我正在尝试使用 MessagePack 在 Erlang 和 Java 中序列化整数。 在 Java 中,我可以用任意数量的 0 填充一个包含一个整数的数组,并且 MessagePack.read()
我正在使用 MessagePack 来编码/解码我的模型并通过 TCP 服务器发送它。此时,我需要为消息定义一个分隔符,以便将接收到的缓冲区切片为正确的 MessagePack 对象。 我的问题是如何
我正在尝试熟悉 Messagepack for Java . 我通过Mqtt获取数据。如果变量不是 null 一切都很好,但变量也可以是 null 在这种情况下我会得到这个异常:Expected In
我需要一种在 python 多处理进程之间通过 zeromq 每秒发送 300 条短消息的快速方法。每条消息都需要包含一个 ID 和 time.time() msgpack 似乎是在通过 zeromq
我正在解码来自 Java 项目中 Apache Beam 管道的 MessagePack 消息。我正在使用 Maven 将 MessagePack 库导入为依赖项: org.msgpack
Java 中的 MessagePack 官方实现将公共(public)字段序列化为数组是否可以接受? 这在什么宇宙中“像 JSON”? 我的案例:我有一个简单的类,如下所示: @Message pub
我想像这样使用 MessagePack 在 C++ 和 Python 语言之间共享结构化数据: { "t" : [ [t00,...,t0N], ... , [tM0,...,tMN] ],
来自 this ,很明显您可以序列化自己的结构。我需要从外部(c 语言)库序列化结构。您如何将 msgpack 与您无法更改的结构/类一起使用? 有点像这样,只是我想做的事情的一个概念: #inclu
在 Java 中,我想使用不可变 POJO 的层次结构来表达我的领域模型。 例如 final ServiceId id = new ServiceId(ServiceType.Foo, "my-foo
我喜欢使用 Messagepack 序列化我的 java 类对象.我的类(class)结构是这样的 public class A { private InnerClass obj; //
寻找一些快速、简单和稳定的 RPC 库我偶然发现了 MessagePack项目似乎非常好。它也在积极开发中。 如果您以任何方式使用它,请您分享您的经验吗? 附言我认为这个问题应该是社区维基 最佳答案
我是 visual studio 和 c++ 的新手。我已经为 c/cpp 下载了 MessagePack 并打开了文件“msgpack_vc8.vcproj”它打开了一个带有一堆 c 文件和 hpp
有人试过用MessagePack使用 Android 应用程序? 有可能吗?我曾尝试使用来自 msgpack-java 的 Jar并收到以下异常: Caused by: java.lang.Excep
在android上使用messagepack,可以序列化/反序列化一个类,但不是绝对正确. 简单的测试类: @Message public class Account { public
我正在尝试使用 MessagePack保存多个结构列表,因为我读到它的性能优于 BinaryFormatter序列化。 我想要做的是接收实时时间序列数据并定期将其定期保存(附加)到磁盘上,例如,如果列
我正在尝试使用 MessagePack 序列化具有接口(interface)类型属性的对象。当我调用 Pack , 它抛出 SerializationException这表示没有为接口(interfa
使用: .NET Core 2.1.x StackExchange.Redis.Extensions 4.0.5 消息包 c-sharp 2.3.85 Azure Redis Azure 应用服务 您
我想使用 JMeter 使用与 JSON 不同的数据序列化格式来对服务器到服务器通信 (Java Spring) 进行基准测试 文章Why not JSON?正在建议MessagePack Messa
嗨,我有一个类: public class Event : Dictionary 属性类型是枚举 反序列化会抛出异常 var @event = new Event { { AttributeType
MessagePack是一种二进制序列化格式,显然可以从 Haskell 和 Python 中使用,我需要在我的项目中混合这些语言。 我需要序列化的结构非常简单: data Citation = Ci
我是一名优秀的程序员,十分优秀!