解压缩的GZPRIPPPRECT READONLYMEMORY< byte>在我做jsondocument.parse之前
WebSocket客户端正在返回 readonlymemory< byte>
。
问题是 jsondocument.parse
由于已压缩缓冲区而失败。在解析之前,我必须以某种方式对其进行解压缩。我该怎么做?我无法真正更改Websocket库代码。
我想要的是 public func< readonlymemory< byte>> datainterPreterBytes =()=>
可选地将这些字节解压缩在此类中。我该怎么做?是否可以解压缩 readonlyMemory<
,并且如果处理程序未使用,则基本上什么都不做。
private static string DecompressData(byte[] byteData)
{
using var decompressedStream = new MemoryStream();
using var compressedStream = new MemoryStream(byteData);
using var deflateStream = new GZipStream(compressedStream, CompressionMode.Decompress);
deflateStream.CopyTo(decompressedStream);
decompressedStream.Position = 0;
using var streamReader = new StreamReader(decompressedStream);
return streamReader.ReadToEnd();
}
片段
private void OnMessageReceived(object? sender, MessageReceivedEventArgs e)
{
var timestamp = DateTime.UtcNow;
_logger.LogTrace("Message was received. {Message}", Encoding.UTF8.GetString(e.Message.Buffer.Span));
// We dispose that object later on
using var document = JsonDocument.Parse(e.Message.Buffer);
var tokenData = document.RootElement;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,如果您有一个字节数组,则将执行此操作:
这类似于上面的摘要,但不需要中间副本:只需直接从
gzipstream
中读取即可。jsondocument.parse
还具有一个接管流的过载,因此您可以使用它并避免另一个无用的副本。不幸的是,您没有字节数组,您有一个
readonlymemory< byte>
。没有办法从readonlymemory< byte>
中创建内存流。老实说,感觉就像是一种监督,就像他们忘了将该功能放入.NET中。因此,这是您的选择。
第一个选项是只需转换
readonlyMemory< byte>
对象与toArray()
>:这确实很简单,但请记住它实际上复制了数据,因此适用于数据,因此大型文档,如果您想避免使用过多的内存,那可能不是一个好主意。
第二个是尝试从内存中提取基础数组。这可以通过
MemoryMarshal.trygetArray
来实现,它为您提供arrayseggentemenseggenseggenseggensegensegensegensegensegensegensegensegensegray
(但是,如果内存实际上不是托管数组)。第三种方式可能会感到肮脏,但是如果您可以使用不安全的代码,可以固定内存的跨度,然后使用
unmanagedMemorystream
:另一个解决方案是编写您自己的
stream < /代码>支持此的类。 流
包装器 目的。如果您不为此使用整个第三方库,那么您可能只能滚动自己的代码太多。So, if you had a byte array, you'd do this:
This is similar to your snippet above, but no need for the intermediate copy: just read straight from the
GzipStream
.JsonDocument.Parse
also has an overload that takes a stream, so you can use that and avoid yet another useless copy.Unfortunately, you don't have a byte array, you have a
ReadOnlyMemory<byte>
. There is no way out of the box to create a memory stream out of aReadOnlyMemory<byte>
. Honestly, it feels like an oversight, like they forgot to put that feature into .NET.So here are your options instead.
The first option is to just convert the
ReadOnlyMemory<byte>
object to an array withToArray()
:This is really straightforward, but remember it actually copies the data, so for large documents it might not be a good idea if you want to avoid using too much memory.
The second is to try and extract the underlying array from the memory. This can be achieved with
MemoryMarshal.TryGetArray
, which gives you anArraySegment
(but might fail if the memory isn't actually a managed array).The third way might feel dirty, but if you're okay with using unsafe code, you can just pin the memory's span and then use
UnmanagedMemoryStream
:The other solution is to write your own
Stream
class that supports this. The Windows Community Toolkit has an extension method that returns aStream
wrapper around the memory object. If you're not okay with using an entire third party library just for that, you can probably just roll your own, it's not that much code.