将C#中的ReadOnlyMemory<byte>转换为byte[]

59
给定ReadOnlyMemory结构,我想将流转换为字符串。
我有以下代码:
var body = ea.Body; //ea.Body is of Type ReadOnlyMemory<byte>
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);

它给出了以下错误。我正在使用最新的C#和.NET CORE 3.1

在这里输入图片描述

很有趣,因为我字面上正在复制粘贴一个名为RabbitMQ的主要产品的Hello World示例,但它无法编译。


我创建了一个问题,以便RabbitMQ可以适应文档:https://github.com/rabbitmq/rabbitmq-website/issues/963 - zanseb
5个回答

97

如果一个东西是只读的,你无法将它放入类型为byte[]的槽中,因为byte[]是可写的,这会破坏其目的。看起来RabbitMQ在2月份更改了他们的API,也许忘记更新示例代码。

一个快速的解决方法是使用.ToArray()

var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);

编辑:既然被接受了,我将根据Dmitry和zenseb提出的更好解决方案进行修改,并使用.Span

var body = ea.Body.Span;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);

5
请注意,GetString方法的重载不包含在 .Net Framework 中。 - Bouke

27

使用 Span 属性 将消息转换为字符串,而无需进行额外的内存分配

var body = ea.Body; //ea.Body is of Type ReadOnlyMemory<byte>
var message = Encoding.UTF8.GetString(body.Span);
Console.WriteLine(" [x] Received {0}", message);

使用Span是否有内存限制,例如仅获取150个消息中的前100个字符? - Jebathon
1
您可以使用 Span 的 Slice 方法访问分配的内存区域的任何片段,默认情况下,Span 返回所有已分配的区域。 - Dmitry Kolchev

13

你需要使用Span属性。

var data = new byte[] { 72, 101, 108, 108, 111 };
var body = new ReadOnlyMemory<byte>(data);
var text = Encoding.UTF8.GetString(body.Span);

Console.WriteLine(text);

Encoding.UTF8.GetString 有一个 ReadOnlySpan<byte> 版本的重载。您可以在 此处 阅读更多信息。


1

我更新了RabbitMQ.Client包,但是在我的Consumer_Received方法中仍然遇到了相同的问题:

private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
        // Code

我查看了 BasicDeliverEventArgs 并发现 Body 现在是一个 ReadOnlyMemory 类型:
public ReadOnlyMemory<byte> Body { get; set; }

正如 Jeff 所说,RabbitMQ 更改了他们的API,因此我认为这与我们以前在互联网上学习到的不同。

要解决问题,我只需要将我的 Body 消息转换为数组(在 Consumer_Received 方法中):
var message = Encoding.UTF8.GetString(e.Body.ToArray());


0
我遇到了同样的问题,并通过以下方法解决:
 public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, ReadOnlyMemory<byte> body) {
 var msg = body.ToArray();
 var message = Encoding.UTF8.GetString(msg);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接