直接将json转为StructureMap序列化字节[]。

问题描述 投票:2回答:1

我有以下JSON(从web套接字接收到的字节[])。

{
    "ev": "T",              // Event Type
    "sym": "MSFT",          // Symbol Ticker
    "x": 4,                 // Exchange ID
    "i": "12345",           // Trade ID
    "z": 3,                 // Tape ( 1=A 2=B 3=C)
    "p": 114.125,           // Price
    "s": 100,               // Trade Size
    "c": [0, 1],           // Trade Conditions
    "t": 1536036818784      // Trade Timestamp ( Unix MS )
}

和一个结构体

struct Trade
{
    [JsonPropertyName("sym")]
    public string  Symbol { get; set; }
    [JsonPropertyName("p")]
    public decimal Price { get; set; }
    ...
}

目前,我正在从JSON到结构化(使用令人惊叹的... Utf8Json lib),然后从结构到 bytes[].

我希望直接从JSON到 MessagePack 序列化字节对象--因为中间的步骤似乎有点多余。

如何在保持上述属性映射的情况下实现这个目标?

理想情况下,由于我以字节[]的形式接收JSON,我想直接使用字节(而不是编码为字符串--或者如果必须这样做,至少编码不会增加很多开销)。

如果使用属性(用于JSON映射)可以让事情变得更简单的话,我是可以接受的。

我目前正在考虑的是 MessagePackWriter 到一个原始缓冲区(如果我需要使用 MemoryManager 或者干脆自己做 byte[] 数组等)。)

我的想法是在解码时直接写流,并消除了 Trade 结构。

private void GetTrade(ref Utf8JsonReader reader, IBufferWriter<byte> bufferWriter)
{
    var trade = new Trade
    {
        TradeConditions = new int[] { }
    };

    // working how to use writer out :)
    var writer = new MessagePackWriter(bufferWriter);

    while (Expect(ref reader, JsonTokenType.PropertyName, JsonTokenType.EndObject))
    {
        var property = reader.GetString();

        switch (property)
        {
            default:
                this.logger.LogError($"decoding {trade.GetType().Name} found unexpected property {property}, skipping");
                reader.Skip();
                break;
            case StreamFieldNames.Symbol:
                trade.Symbol = ExpectString(ref reader, StreamFieldNames.Symbol);
                break;
            case StreamFieldNames.ExchangeId:
                trade.ExchangeId = ExpectInt(ref reader, StreamFieldNames.ExchangeId);
                break;
            case StreamFieldNames.TradeId:
                trade.TradeId = ExpectString(ref reader, StreamFieldNames.TradeId);
                break;
            case StreamFieldNames.Tape:
                trade.Tape = ExpectInt(ref reader, StreamFieldNames.Tape);
                break;
            case StreamFieldNames.Price:
                trade.Price = ExpectDecimal(ref reader, StreamFieldNames.Price);
                break;
            case StreamFieldNames.TradeSize:
                trade.TradeSize = ExpectDecimal(ref reader, StreamFieldNames.TradeSize);
                break;
            case StreamFieldNames.TradeConditions:
                trade.TradeConditions = ExpectIntArray(ref reader, StreamFieldNames.TradeConditions);
                break;
            case StreamFieldNames.Timestamp:
                trade.Timestamp = ExpectUnixTimeMilliseconds(ref reader, StreamFieldNames.Timestamp);
                break;
        }
    }
    return trade;
}
c# msgpack utf8json
1个回答
0
投票

如果我理解正确的话,你得到的是字节[],并且想在不将字节[]转换为字符串的情况下得到交易结构?在这种情况下,你可以使用 元帅 库来将非托管对象转换为托管对象。

    public T ByteArrayToStructure<T>(byte[] bytes) where T : struct
    {
        T result;
        GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        try
        {
            result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        }
        finally
        {
            handle.Free();
        }
        return result;
    }

你需要加入 System.Runtime.InteropServices 来实现这个功能。在这种情况下,byte[]将必须包含结构中所有声明的字段,所以你不需要任何属性。你可以在 代码工程 网站是如何工作的。虽然这个问题在C或C++中很容易解决,但在C#中,我们没有指针,这为我们减轻了生活的压力,但也删除了一些功能。

© www.soinside.com 2019 - 2024. All rights reserved.