Reputation: 13
I am starting a new web application project where a user can upload a .csv
file so that I can process the file.
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.
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.
[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.
Upvotes: 1
Views: 1007
Reputation: 93173
When reading from a Stream, the current position is updated accordingly. As an example, imagine the following steps:
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.
Relating this to your example, the call to await file.CopyToAsync(stream)
advances the stream's position to EOF. As such, when you wrap a StreamReader
around it, there's nothing left to read. 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.
To complicate things a little, Streams can be forward-only, meaning that it is not possible to go backwards once data has been read. As you are working with a FileStream
, I think you are able to go back to the beginning, like so:
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
Upvotes: 4