简体   繁体   English

StreamReader.ReadLine()不消耗流

[英]StreamReader.ReadLine() doesn't consume the stream

I am starting a new web application project where a user can upload a .csv file so that I can process the file. 我正在启动一个新的Web应用程序项目,用户可以在其中上传.csv文件,以便我可以处理该文件。

Currently I am able to let the user upload the file but when I try to use the StreamReader to read from the stream that generated from the file, it seems that the StreamReader cannot read from the stream properly. 当前,我可以让用户上传文件,但是当我尝试使用StreamReader读取从文件生成的流时,似乎StreamReader无法正确读取该流。

By the way, for the upload file part I followed the Microsoft tutorial here 顺便说一句,在上传文件部分,我跟着微软教程这里

Here is the code for the 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>

Here is my code for the Controller 这是我的控制器代码

The len, len2 and p are variables for debugging purposes. 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
        }
    }

Any advice or help will be appreciated. 任何建议或帮助将不胜感激。

When reading from a Stream, the current position is updated accordingly. 从Stream读取时,当前位置会相应更新。 As an example, imagine the following steps: 例如,设想以下步骤:

  1. The position starts off at 0 (the beginning of the stream). 位置从0(流的开头)开始。
  2. A single byte is read - This updates the position to 1. 读取一个字节-将位置更新为1。
  3. Another byte is read - This updates the position to 2. 读取另一个字节-将位置更新为2。

If there were only two bytes in the stream, the position is now considered to be EOF - It is no longer possible to read additional bytes, as they've already been read. 如果流中只有两个字节,则该位置现在被认为是EOF-无法再读取其他字节,因为已经读取了它们。

Relating this to your example, the call to await file.CopyToAsync(stream) advances the stream's position to EOF. 与您的示例相关,调用await file.CopyToAsync(stream)将流的位置前进到EOF。 As such, when you wrap a StreamReader around it, there's nothing left to read. 这样,当您将StreamReader包裹起来时,就没什么可读取的了。 The process is the same for writing - The CopyToAsync operation is advancing both the input and the output streams, resulting in both streams sitting at EOF once the operation completes. 写入的过程相同CopyToAsync操作同时推进输入流和输出流,一旦操作完成,两个流都位于EOF处。

To complicate things a little, Streams can be forward-only, meaning that it is not possible to go backwards once data has been read. 为了使事情复杂一点,Streams只能是前向的,这意味着一旦读取数据就不可能向后移动。 As you are working with a FileStream , I think you are able to go back to the beginning, like so: 在使用FileStream ,我认为您可以回到开始,就像这样:

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

You could also use stream.Seek(0, SeekOrigin.Begin) , as mentioned in this answer: Stream.Seek(0, SeekOrigin.Begin) or Position = 0 您还可以使用stream.Seek(0, SeekOrigin.Begin) ,如此答案中所述: Stream.Seek(0,SeekOrigin.Begin)或Position = 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM