首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#内存到TextReader

C#内存到TextReader
EN

Stack Overflow用户
提问于 2020-08-12 17:54:36
回答 1查看 654关注 0票数 4

TextReader对象获取Memory<byte>实例的最佳方法是什么?

我可以写这样的东西:

代码语言:javascript
复制
using (var stream = new MemoryStream(body.ToArray()))
using (var reader = new StreamReader(stream))
{
}

但也许还有更好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-12 20:52:48

StreamReader将自动释放底层Stream

#1 最简单的方式

代码语言:javascript
复制
Memory<byte> memory = GetSomeData();
using TextReader reader = new StreamReader(new MemoryStream(memory.ToArray()));
// some code

但是在这里,您要将整个内存内容复制到另一个数组中,这会消耗内存,并给垃圾收集器带来更多的工作。特别是如果数组包含大量数据,则不建议这样做。

在不分配新数组的情况下,还有另一种方法。

#2最佳方法(建议节省内存)

代码语言:javascript
复制
Memory<byte> memory = GetSomeData();
if (MemoryMarshal.TryGetArray(memory, out ArraySegment<byte> segment))
{
    using TextReader reader = new StreamReader(new MemoryStream(segment.Array, segment.Offset, segment.Count));
    // some code
}

换句话说,ArraySegment将源内存区域作为数组返回。

测试

下面是一个使用它的示例(基于.NET Core3.1Console应用程序)。

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        string text = "Hello World!";
        byte[] data = Encoding.UTF8.GetBytes(text);
        Memory<byte> memory = data;

        byte[] data1 = memory.ToArray();
        Console.WriteLine("data == data1: {0}", data == data1);
            
        if (MemoryMarshal.TryGetArray(memory, out ArraySegment<byte> segment))
        {
            byte[] data2 = segment.Array;
            Console.WriteLine("data == data2: {0}", data == data2);
        }

        Console.WriteLine();

        Console.WriteLine("Test 1");
        Test1(text);

        Console.WriteLine();

        Console.WriteLine("Test 2");
        Test2(text);

        Console.ReadKey();
    }

    private static void Test1(string text)
    {
        Memory<byte> memory = Encoding.UTF8.GetBytes(text);
        byte[] data = memory.ToArray();
        ReadItTwice(memory, data);
    }

    private static void Test2(string text)
    {
        Memory<byte> memory = Encoding.UTF8.GetBytes(text);
        if (MemoryMarshal.TryGetArray(memory, out ArraySegment<byte> segment))
        {
            byte[] data = segment.Array;
            ReadItTwice(memory, data);
        }
    }

    private static void ReadItTwice(Memory<byte> memory, byte[] data)
    {
        using MemoryStream ms = new MemoryStream(data);
        using TextReader sr = new StreamReader(ms);
        Console.WriteLine("Before change: {0}", sr.ReadToEnd());
        if (MemoryMarshal.TryGetArray(memory, out ArraySegment<byte> segment))
            segment.Array[0] = (byte)'_'; // change first symbol
        ms.Position = 0;
        Console.WriteLine("After change: {0}", sr.ReadToEnd());
    }
}

输出

代码语言:javascript
复制
data == data1: False
data == data2: True

Test 1
Before change: Hello World!
After change: Hello World!

Test 2
Before change: Hello World!
After change: _ello World!
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63382206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档