在我正在创建的商业应用中,我们允许管理员上传包含某些数据的CSV文件,这些数据会被解析并输入到我们的数据库中(所有相应的错误处理都在发生等)。
作为升级到.NET 4.5的一部分,我不得不更新此代码的一些方面,并且在我这样做时,我遇到了使用MemoryStream来处理上传文件的this answer人而不是暂时保存到文件系统。我没有真正的理由要改变(也许它甚至可能不好),但我想尝试一下学习。所以,我快速换掉了这段代码(由于上传其他元数据而从强类型模型中删除):
HttpPostedFileBase file = model.File;
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
file.SaveAs(path);
CsvParser csvParser = new CsvParser();
Product product = csvParser.Parse(path);
this.repository.Insert(product);
this.repository.Save();
return View("Details", product);
到此:
using (MemoryStream memoryStream = new MemoryStream())
{
model.File.InputStream.CopyTo(memoryStream);
CsvParser csvParser = new CsvParser();
Product product = csvParser.Parse(memoryStream);
this.repository.Insert(product);
this.repository.Save();
return View("Details", product);
}
不幸的是,当我这样做时,事情就会中断 - 我的所有数据都是以空值出现的,看起来好像MemoryStream中没有任何内容(尽管我对此并不乐观)。我知道这可能是一个很长的镜头,但是有什么显而易见的我在这里或者我可以做些什么来更好地调试它?
答案 0 :(得分:6)
您需要添加以下内容:
model.File.InputStream.CopyTo(memoryStream);
memoryStream.Position = 0;
...
Product product = csvParser.Parse(memoryStream);
当您将文件复制到MemoryStream中时,指针会移动到流的末尾,因此当您尝试读取它时,您将获得一个空字节而不是流数据。您只需要将位置重置为开头,即0。
答案 1 :(得分:2)
我相信你的记忆问题是它的位置设置到最后,我猜你的CSVParser只是从那时开始处理,没有数据。
要解决此问题,您只需将memoryStream位置设置为0,然后再使用csvParser解析它。
memoryStream.Position = 0;