【问题标题】:Read Text file without copying to hard disk读取文本文件而不复制到硬盘
【发布时间】:2019-12-13 02:45:22
【问题描述】:

我正在使用 Asp.Net Core 3.0,我发现自己处于客户端将文本文件传递给我的 API 的情况,然后 API 将使用我的函数将文本文件解析为数据模型已创建名为 ParseDataToModel(),然后使用实体框架将该数据模型存储到数据库中。由于我的代码是将文件解析为数据模型,所以如果没有必要,我真的不需要将其复制到硬盘上。关于Streams,我没有太多的知识,而且我用谷歌搜索了很多,但我想知道是否有一种方法可以检索上传文件的字符串数据,而无需将它们实际复制到硬盘驱动器?这似乎是一个不必要的额外步骤......下面是我的文件上传和插入数据库的代码:

 [HttpPost("upload"), DisableRequestSizeLimit]
    public IActionResult Upload()
    {
        var filePaths = new List<string>();
        foreach(var formFile in Request.Form.Files)
        {
            if(formFile.Length > 0)
            {
                var filePath = Path.GetTempFileName();
                filePaths.Add(filePath);

                using(var stream = new FileStream(filePath, FileMode.Create))
                {
                    formFile.CopyTo(stream);
                }
            }
        }

        BaiFiles lastFile = null;
        foreach(string s in filePaths)
        {
            string contents = System.IO.File.ReadAllText(s);
            BaiFiles fileToCreate = ParseFileToModel(contents);


            if (fileToCreate == null)
                return BadRequest(ModelState);

            var file = _fileRepository.GetFiles().Where(t => t.FileId == fileToCreate.FileId).FirstOrDefault();

            if (file != null)
            {
                ModelState.AddModelError("", $"File with id {fileToCreate.FileId} already exists");
                return StatusCode(422, ModelState);
            }

            if (!ModelState.IsValid)
                return BadRequest();

            if (!_fileRepository.CreateFile(fileToCreate))
            {
                ModelState.AddModelError("", $"Something went wrong saving file with id {fileToCreate.FileId}");
                return StatusCode(500, ModelState);
            }

            lastFile = fileToCreate;


        }
        return CreatedAtRoute("GetFile", new { fileId = lastFile.FileId }, lastFile);
    }

将所有数据保存在内存中而不是将它们复制到硬盘驱动器会很好,只是转身打开它来阅读文本......如果这是不可能的,我深表歉意,或者如果这个问题以前被问过。我确定它有,而且我只是没有在谷歌上搜索正确的关键字。否则,我可能是错的,它已经在做我想要的 - 但System.IO.File.ReadAllText() 让我觉得它被复制到某个地方的临时目录。

在使用下面约翰的答案后,有兴趣的人可以参考以下修改后的代码:

[HttpPost("upload"), DisableRequestSizeLimit]
    public IActionResult Upload()
    {
        var filePaths = new List<string>();
        BaiFiles lastFile = null;
        foreach (var formFile in Request.Form.Files)
        {
            if (formFile.Length > 0)
            {
                using (var stream = formFile.OpenReadStream())
                {
                    using (var sr = new StreamReader(stream))
                    {
                        string contents = sr.ReadToEnd();

                        BaiFiles fileToCreate = ParseFileToModel(contents);


                        if (fileToCreate == null)
                            return BadRequest(ModelState);

                        var file = _fileRepository.GetFiles().Where(t => t.FileId == fileToCreate.FileId).FirstOrDefault();

                        if (file != null)
                        {
                            ModelState.AddModelError("", $"File with id {fileToCreate.FileId} already exists");
                            return StatusCode(422, ModelState);
                        }

                        if (!ModelState.IsValid)
                            return BadRequest();

                        if (!_fileRepository.CreateFile(fileToCreate))
                        {
                            ModelState.AddModelError("", $"Something went wrong saving file with id {fileToCreate.FileId}");
                            return StatusCode(500, ModelState);
                        }

                        lastFile = fileToCreate;
                    }
                }

            }  
        }
        if(lastFile == null)
           return NoContent();
        else
            return CreatedAtRoute("GetFile", new { fileId = lastFile.FileId }, lastFile);
    }

【问题讨论】:

  • @John_ReinstateMonica WOW。我之前尝试过,但试图将我的 formFile 直接传递给 StreamReader (NOOB)。我没想到要先使用 OpenReadStream,然后将 STREAM 传递给 StreamReader……非常感谢!!
  • 将很快添加答案:)

标签: c# asp.net-core io


【解决方案1】:

System.IO.File.ReadAllText(filePath) 是一种方便的方法。它本质上是这样做的:

string text = null;

using (var stream = FileStream.OpenRead(filePath))
using (var reader = new StreamReader(stream))
{
    text = reader.ReadToEnd();
}

FormFile 实现了一个OpenReadStream 方法,因此您可以简单地使用它来代替上面的stream

string text = null;

using (var stream = formFile.OpenReadStream())
using (var reader = new StreamReader(stream))
{
    text = reader.ReadToEnd();
}

【讨论】:

  • 非常感谢!对不起,我的菜鸟大声笑,这是漫长的一天!
猜你喜欢
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-27
  • 2012-05-22
  • 1970-01-01
  • 2011-10-12
相关资源
最近更新 更多