假设您执行以下操作:

public List<string> Index(IFormFile file){

    //extract list of strings from the file
    return new List<string>();
}

我已经找到了许多将文件保存到驱动器的示例,但是如果我想跳过此步骤,而直接从IFormFile将文本行读入内存中的数组,该怎么办?

最佳答案

IFormFile的抽象有一个 .OpenReadStream 方法。
为了避免产生大量不希望有的潜在分配,我们应该一次读取一行,并从读取的每一行中建立列表。另外,我们可以将此逻辑封装在扩展方法中。 Index操作最终看起来像这样:

public List<string> Index(IFormFile file) => file.ReadAsList();

相应的扩展方法如下所示:

public static List<string> ReadAsList(this IFormFile file)
{
    var result = new StringBuilder();
    using (var reader = new StreamReader(file.OpenReadStream()))
    {
        while (reader.Peek() >= 0)
            result.AppendLine(reader.ReadLine());
    }
    return result;
}

同样,您也可以使用async版本:

public static async Task<string> ReadAsStringAsync(this IFormFile file)
{
    var result = new StringBuilder();
    using (var reader = new StreamReader(file.OpenReadStream()))
    {
        while (reader.Peek() >= 0)
            result.AppendLine(await reader.ReadLineAsync());
    }
    return result.ToString();
}

另外,您可以使用 ObjectPool<StringBuilder> 和现代C#8功能。

public static async Task<string> ReadAsStringAsync(
    this IFormFile file, Object<StringBuilder> pool)
{
    var builder = pool.Get();
    try
    {
        using var reader = new StreamReader(file.OpenReadStream());
        while (reader.Peek() >= 0)
        {
            builder.AppendLine(await reader.ReadLineAsync());
        }
        return builder.ToString();
    }
    finally
    {
        pool.Return(builder);
    }
}

然后,您可以通过以下方式使用此版本:

public Task<List<string>> Index(
    IFormFile file, [FromServices] ObjectPool<StringBuilder> pool) =>
    file.ReadAsListAsync(pool);

关于parsing - 如何从ASP.NET Core中的IFormFile读取文本文件的行到内存?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40045147/

10-09 20:34