StreamReader.ReadLine()不使用流

时间:2017-10-04 19:35:25

标签: c# asp.net-mvc asp.net-core-2.0

我正在启动一个新的Web应用程序项目,用户可以上传.csv文件,以便我可以处理该文件。

目前我可以让用户上传文件,但是当我尝试使用StreamReader从文件生成的流中读取时,似乎StreamReader无法读取正确地流。

顺便说一句,对于上传文件部分,我遵循了Microsoft教程here

以下是View的代码。

<form method="post" enctype="multipart/form-data" asp-controller="Upload" asp-action="Upload">
<div class="form-group">
    <div class="col-md-10">
        <p>Upload one or more files using this form:</p>
        <input type="file" name="files" >
    </div>
</div>
<div class="form-group">
    <div class="col-md-10">
        <input type="submit" value="Upload" />
    </div>
</div>

这是我的Controller代码

len,len2和p是用于调试目的的变量。

[HttpPost]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        if (file != null && file.Length > 0)
        {
            var filePath = Path.GetTempFileName(); //Note: May throw excepetion when temporary file exceeds 65535 per server
            var stream = new FileStream(filePath, FileMode.Create);
            await file.CopyToAsync(stream);//
            long len = stream.Length;// 412 bytes
            StreamReader reader = new StreamReader(stream);//*
            int p = reader.Peek();//currently the next character is EoF
            var val = reader.ReadLine();
            long len2 = stream.Length;// 412 bytes
            bool end = reader.EndOfStream;// true

            //do some stuff here

            return RedirectToAction("Success");
        }
        else
        {
            return RedirectToAction("Upload_fail");//file not found
        }
    }

任何建议或帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

从Stream中读取时,当前位置会相应更新。例如,想象以下步骤:

  1. 该位置从0开始(流的开头)。
  2. 读取单个字节 - 这会将位置更新为1.
  3. 读取另一个字节 - 这会将位置更新为2。
  4. 如果流中只有两个字节,则该位置现在被视为EOF - 不再可能读取其他字节,因为它们已被读取。

    将此与您的示例相关联,对await file.CopyToAsync(stream)的调用将流的位置提升为EOF。因此,当您在其周围包裹StreamReader时,没有什么可以阅读的。写入过程相同 - CopyToAsync操作正在推进输入和输出流,导致两个流在操作完成后都位于EOF。

    为了使事情稍微复杂化,Streams可以是仅向前的,这意味着一旦读取数据就不可能倒退。当您使用FileStream时,我认为您可以回到开头,就像这样:

    await file.CopyToAsync(stream);
    stream.Position = 0;
    

    您还可以使用stream.Seek(0, SeekOrigin.Begin),如本回答中所述:Stream.Seek(0, SeekOrigin.Begin) or Position = 0