我需要在asp.net mvc应用程序中解析并自定义保存(不使用SaveAs
)HttpPostedFileBase
。
我的代码是:
private ReportViewModel LoadFile(Stream stream, string fileName)
{
MapParser mapParser = new MapParser(stream);
try
{
mapParser.Parse();
}
....
stream.position = 0;
SaveFile(memStream2, Server.MapPath("~/Uploads/Maps/" +
(map.Id + "." + ext)));
....
}
public static void SaveFile(Stream inputStream, string filePath)
{
using (Stream file = System.IO.File.Create(filePath))
{
inputStream.CopyTo(file);
}
}
LoadFile(loadMapVM.MapFile.InputStream, loadMapVM.MapFile.FileName)
所以,我的Parse()
方法工作得很好,但在SaveAs
方法之后创建了0字节的文件。我认为,我应该在Parse()
之后克隆或重新打开以启动我的流。但我该怎么做呢?
编辑
我的MapParser代码:
public MapParser(Stream stream)
{
using(stream)
{
IWorkbook workBook = null;
if (POIXMLDocument.HasOOXMLHeader(stream))
workBook = new XSSFWorkbook(stream);
if (POIFSFileSystem.HasPOIFSHeader(stream))
workBook = new HSSFWorkbook(stream);
if (workBook == null)
throw new MapParserException(MapParserError.InvalidFileFormat);
mSheet = workBook.GetSheetAt(0);
}
}
public void Parse()
{
mData = new Map();
mData.UnitCode = mSheet.GetRow(0).GetCell(5).GetSafeValue();
if (mData.UnitCode == "")
throw new MapParserException(MapParserError.NoUnitCode, 0, 5);
....
}
在一般情况下,不应假设Stream
s是可重复的;这适用于,尤其是在谈论通过导线传输的数据时。如果您读取了Parse
中的数据,那么您已经消耗了数据:它不见了。
选项:
- 缓冲内存中的所有数据(
Stream.CopyTo
到MemoryStream
)-如果您将其限制为中等大小,这是可能的,但如果数据可能很大,这不是一个好的选择 - 在向文件系统写入时执行
Parse
;高效但难以实施 - 将数据缓冲到磁盘(基本上先执行
SaveFile
),然后检查您写入的内容(将其写入其他位置,如果内容不好则删除文件,如果内容良好则移动文件)