【问题标题】:ReadOnlySequence<byte> parsingReadOnlySequence<byte> 解析
【发布时间】:2019-05-25 17:47:50
【问题描述】:

所以我开始尝试使用 Span 进行消息解析代码。 尽管 api 看起来很容易理解,但我似乎无法找到任何将切片转换为值的方法。 例如,我想将 ReadOnlySequence 转换为 int。 当然我可以调用 ToArray 并使用 BitConverter 但这实际上会创建一个新数组,这是我试图避免的。

这是我如何获得切片的示例

        var DHCP_OP = buffer.Slice(0, 1);          
        var DHCP_HTYPE = buffer.Slice(1, 1);
        var DHCP_HLEN = buffer.Slice(2, 1);
        var DHCP_HOPS = buffer.Slice(3, 1);
        var DHCP_XID = buffer.Slice(4, 4);
        var DHCP_SECS = buffer.Slice(8, 2);
        var DHCP_FLAGS = buffer.Slice(10, 2);
        var DHCP_CI_ADDR = buffer.Slice(12, 4);
        var DHCP_YI_ADDR = buffer.Slice(16, 4);
        var DHCP_SI_ADDR = buffer.Slice(20, 4);
        var DHCP_GI_ADDR = buffer.Slice(24, 4);
        var DHCP_CH_ADDR = buffer.Slice(28, 16);
        var DHCP_SNAME = buffer.Slice(44, 64);
        var DHCP_FILE = buffer.Slice(108, 128);

这就是我可能转换为 int 的方式

      var DHCP_OP = buffer.Slice(0, 1).ToArray();
      var integer = BitConverter.ToInt32(DHCP_OP, 0);

那么这里有哪些选项?我错过了什么还是 ToArray 是唯一的选择? 谢谢。

【问题讨论】:

  • 由于 .NET Core 2.1 BitConverter.ToInt32 有一个带有 ReadOnlySpan&lt;byte&gt; 参数的重载(戳文档通常有助于解决此类问题...)
  • 嗯,我的库目标是 .NET 标准,所以唯一的方法是重新定位到核心?
  • NET Standard 2.1 和更高版本还包括使用 ReadOnlySpan 的重载(这并非巧合,因为 .NET Core 的“类库”是 .NET Standard 库)
  • 顺便说一下,以防万一您还不知道,Span 隐式转换为 ReadOnlySpan。 (因此,您无需通过代码将 Span 的用法更改为 ReadOnlySpan。幸运的是,没有必要。)
  • 因此,如果目标是 .net 核心,我似乎只能使用这些重载 :( 现在我从 PipeReader 获得 ReadOnlySequence 并且似乎重载需要 ReadOnlySpan。有点对如何在不重新分配内存的情况下进行转换感到困惑。

标签: c#


【解决方案1】:

这是 .NET Core 3 中的 addedSequenceReader&lt;T&gt;。 它提供了尝试从ReadOnlySequence&lt;T&gt; 实例中读取值的方法(当然,只有在有足够的可用数据时才会成功)。

SequenceReader&lt;T&gt; 已在此处记录:

阅读简单的Int32 的用法是:

// using System.Buffers;

ReadOnlySequence<byte> buffer = ...;

SequenceReader<byte> reader = new SequenceReader<byte>(buffer);
if (reader.TryReadLittleEndian(out int integer))
{
    // do something with the read value, the reader advanced by sizeof(int)
}
else
{
    // possibly abort parsing as you cannot read further yet
}

【讨论】:

    【解决方案2】:

    这可能在几个月前就解决了,但以防万一其他人在这里偶然发现相同的东西;

    您可能正在寻找System.Runtime.InteropServices.MemoryMarshal。如果您使用 LayoutType.Sequential 或 Explicit 定义结构,您可以简单地调用 MemoryMarshal.Read&lt;DhcpDataStruct&gt;(mySpan) 来获取填充实例。

    【讨论】:

    • MemoryMarshal.Read 方法仅支持 ReadOnlySpan,不支持 ReadOnlySequence 实例。
    • 噢!我不知何故错过了那部分,只关注Span 提及。
    • 不用担心。在我发布答案之前,我什至不知道除了 Spans 之外还存在像序列这样的东西:d
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    相关资源
    最近更新 更多