如何在 C# 流中读取非托管内存流?
我可以使用 UnmanagedMemoryStream 读取 C# 中的非托管内存,但如何执行相反的操作呢?
我想从托管流直接读取到非托管内存,而不是先读入 byte[] 然后复制。我正在对大量请求进行异步流读取,因此增加的内存非常重要(更不用说额外的副本)。
I can read unmanaged memory in C# using UnmanagedMemoryStream, but how can I do the reverse?
I want to read from a managed stream directly into unmanaged memory, instead of first reading into a byte[] and then copying. I'm doing async stream reading on a large number of requests, so the added memory is significant (not to mention the additional copy).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您有已知的目标缓冲区并且知道数据有多大,这实际上并不太难。再次强调,关键的实现是 UnmanagementMemoryStream只是一系列本机字节的薄包装。
您想要做的是以通常的方式获取指向本机目标缓冲区的指针。然后您可以在其之上构造一个可写 UnmanagedMemoryStream。将源流复制到目标流,瞧!单个副本已将您从托管内存世界转移到本机内存世界。在 C++/CLI 中,它看起来像这样:
This actually isn't too hard if you have a known destination buffer and you know how big your data is. The key realization, once again, is that an UnmanagedMemoryStream is just a thin wrapper around a sequence of native bytes.
What you want to do is grab a pointer to your native destination buffer in the usual fashion. Then you can construct a writable UnmanagedMemoryStream on top of it. Copy your source stream to the destination stream and voila! A single copy has moved you from the managed memory world to the native memory world. In C++/CLI, it looks something like this:
我认为这实际上是不可能的。当您谈论托管流时,我想您指的是 System.IO.Stream 或其子类的实例。
该类的成员以 byte[] 作为参数,这是一个托管类。
我想您最接近的是创建一个托管 byte[],然后在不安全的块中创建一个 byte*,然后将 byte* 传递给需要非托管引用的任何内容:
但这并不完全是您所要求的对于
编辑:不过要小心。您提到了有关异步读取的内容。一旦超出固定边界,GC 可能会在内存中移动数组。如果您将指针传递给某个继续在不同线程中运行的“不安全”函数,则该指针将指向无效的内存位置。
I think that it is not really possible. When you talk about a managed stream, I suppose you are refering to an instance of System.IO.Stream or a subclass hereof.
The members of this class take byte[] as a parameter, and that is a managed class.
I guess that the closest you can come is creating a managed byte[], and then creating a byte* in an unsafe block, and then passing the byte* to whatever needs an unmanaged reference:
But that is not exactly what you're asking for
edit: Be careful though. You mention something about async reads. As soon as you're outside the fixed boundary, the GC may move the array around in memory. And if you've passed the pointer to some "unsafe" function that continues to operate in a different thread, the pointer will point to an invalid memory location.
托管流始终需要一个对有效
byte[]
对象的“托管”对象引用。但是,您可以使用固定的托管字节[]来代替非托管内存分配,因此也可以将其作为非托管内存块进行访问:The managed stream will always need a "managed" object reference to a valid
byte[]
object. However, you can use a managedbyte[]
which is pinned en lieu of a unmanaged memory allocation and therefore make it accessible as an unmanaged memory block also:您可以使用 C# 并通过 Windows API 直接将文件读取到非托管内存中。
如果您想从 FileStream 中读取数据,这可能会有所帮助。检查 FileStream 实现 并执行类似的操作。
You can use C# and read file by Windows API directly into unmanaged memory.
If you want to read from FileStream, this could be helpful. Check FileStream implementation and do something similar.