我正在尝试使用接受Memory<T>
的{{3}}。
这是示例代码:(.NET Core 2.1)
static async Task Main(string[] args)
{
string code = "Hello, World";
var memoryStream = Encoding.UTF8.GetBytes(code.ToCharArray(), 0, code.Length);
using (var stream = new MemoryStream(memoryStream))
using (var reader = new StreamReader(stream))
{
// var text = await reader.ReadLineAsync();
// Console.WriteLine(text); -> Outputs: Hello, World
Memory<char> memory = new Memory<char>();
await reader.ReadAsync(memory);
Console.WriteLine("Memory<char> length:" + memory.Length);
}
}
代码尝试通过StreamReader
读取字符串内容并填充Memory<char>
。但是,代码在Memory<char>
的长度上始终输出0。
使用此方法填充Memory<char>
的正确方法是什么?
我的.csproj
文件内容:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
</Project>
答案 0 :(得分:1)
有效的解决方案是使用缓冲区初始化内存,并注意ReadAsync的返回值,以使您知道已读取了多少个字符(而不是字节)。
您确实遇到了以下问题:Memory是一种结构,该结构始终允许您创建不带参数的实例,尽管从API使用角度来看,这是不允许的。
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace ReadMemory
{
class Program
{
public static async Task Main(string[] args)
{
string code = "Hello, World";
var memoryStream = Encoding.UTF8.GetBytes(code.ToCharArray(), 0, code.Length);
using (var stream = new MemoryStream(memoryStream))
using (var reader = new StreamReader(stream))
{
Memory<char> memory = new Memory<char>(new char[1024]); // Init with backing buffer. Otherwise you are trying to read 0 bytes into a zero sized buffer.
int charsRead = await reader.ReadAsync(memory);
Console.WriteLine($"Memory<char> len: {memory.Length}, bytes read: {charsRead}");
}
}
}
}
回答第二个问题。是的,您可以使用ReadAsync(char [] ...)代替内存。它们是等效的,因为在引擎盖下它将作为System.Memory进一步传递,然后将实际读数转换为Span。 参见
public virtual System.Threading.Tasks.Task<int> ReadAsync(char[] buffer, int index, int count)
{
return this.ReadAsyncInternal(new Memory<char>(buffer, index, count), default(System.Threading.CancellationToken)).AsTask();
}