为什么CsvHelper无法从MemoryStream读取? [英] Why CsvHelper not reading from MemoryStream?

查看:101
本文介绍了为什么CsvHelper无法从MemoryStream读取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将上载的csv文件转换为对象,因此我可以将其保存在db中. 在控制器中,我正在使用CsvHeler

I am trying to convert an uploaded csv file to an object, so i can save in db. In the controller I am using CsvHeler

但是看起来这只有在我首先保存文件并从中读取时才有效. CsvHelper无法直接从内存流中处理文件内容.在第一个GetRecords下面的代码中,返回空

But looks like this only works if I first save the file and read from it. CsvHelper is not able to process the file contents directly from memory stream. In the code below the first GetRecords returns empty

    [HttpPost]
    [Route(ApiRoutes.EodVariationMarginPlugs)]
    public async Task<IActionResult> UploadPlugAsync(IFormFile filePayload)
    {

        if (filePayload.Length > 0)
        {

            using (var stream = new MemoryStream())
            {
                filePayload.CopyTo(stream);
                using (var reader = new StreamReader(stream))
                using (var csv = new CsvReader(reader))
                {
                    csv.Configuration.RegisterClassMap<EodVariationMarginPlugMap>();
                    csv.Configuration.MissingFieldFound = null;
                    var records = csv.GetRecords<EodVariationMarginPlug>().ToList(); // record count is 0
                    foreach (var p in records)
                    {
                        p.CreatedAt = DateTimeOffset.Now;
                        p.CreatedBy = HttpContext.User.Identity.Name;
                    }
                    await _repository.InsertPlugsAsync(records);
                }
            }

        var fileName = ContentDispositionHeaderValue
            .Parse(filePayload.ContentDisposition)
            .FileName.ToString().Trim('"');
            var path = Path.Combine(Path.GetTempPath(), fileName);
            using (var fileStream = new FileStream(path, FileMode.Create))
            {
                await filePayload.CopyToAsync(fileStream);
            }
            var textReader = System.IO.File.OpenText(path);
            using (var csv = new CsvReader(textReader))
            {
                csv.Configuration.RegisterClassMap<EodVariationMarginPlugMap>();
                csv.Configuration.MissingFieldFound = null;
                var records = csv.GetRecords<EodVariationMarginPlug>().ToList();
                foreach (var p in records)
                {
                    p.CreatedAt = DateTimeOffset.Now;
                    p.CreatedBy = HttpContext.User.Identity.Name;
                }
                await _repository.InsertPlugsAsync(records);
            }
        }
        return Ok();
    }

推荐答案

MemoryStream是二进制的.它以字节为单位.您需要一些处理字符的东西.好消息是您尝试过;你有这个:

MemoryStream is binary. It deals in bytes. You need something that deals in characters. The good news is you attempted that; you have this:

using (var reader = new StreamReader(stream))

StreamReader实现TextReader,它使用字符而不是字节.耶!坏消息是在此行之后立即创建了StreamReader:

StreamReader implements TextReader, which works with characters rather than bytes. Yay! The bad news is the StreamReader is created right after this line:

filePayload.CopyTo(stream);

问题是该行使流指向数据的 end .当您尝试从中读取内容时,流中什么也没剩下.

The problem was that line left the stream pointed at the end of the data. When you try to read from it, there's nothing left in the stream.

要解决此问题,您需要做的就是回到起点.因此:

All you should need to do to fix this is seek back to the beginning. So this:

using (var stream = new MemoryStream())
{
    filePayload.CopyTo(stream);
    using (var reader = new StreamReader(stream))

成为这个:

using (var stream = new MemoryStream())
{
    filePayload.CopyTo(stream);
    stream.Seek(0, SeekOrigin.Begin)

    using (var reader = new StreamReader(stream))

这篇关于为什么CsvHelper无法从MemoryStream读取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆