ASP.NET的File方法直接返回MemoryStream报错,存临时文件则正常是什么原因
问题根因
直接返回MemoryStream报错的核心原因是:写入完Tar内容的流读写位置处于流的末尾,ASP.NET Core处理FileResult时会从流的当前Position位置开始读取内容,此时读不到任何有效数据,触发500内部错误。
你之前写入临时文件再读取的写法,新打开的文件流默认从起始位置开始读取,所以可以正常运行。你设置的IsStreamOwner = false已经避免了TarArchive释放时连带销毁MemoryStream,因此不需要修改这部分逻辑。
解决方案
方案1:修改CreateTar方法,返回前重置流位置(推荐)
在TarArchive写入完成后,手动将MemoryStream的位置重置为起始点即可,修改后的代码如下:
public static Stream CreateTar (string dir) { MemoryStream stream = new(); using (TarArchive tarArchive = TarArchive.CreateOutputTarArchive(stream)) { tarArchive.IsStreamOwner = false; // 注意原代码此处反斜杠需要转义,应写为'\\'否则会触发编译错误 tarArchive.RootPath = dir.Replace('\\', '/'); if (tarArchive.RootPath.EndsWith("/")) tarArchive.RootPath = tarArchive.RootPath.Remove(tarArchive.RootPath.Length - 1); AddDirectoryFilesToTar(tarArchive, dir); } // 新增此行,重置流读写位置到起始点 stream.Position = 0; return stream; }
修改完成后,你直接返回MemoryStream的代码即可正常运行。
方案2:调用处手动重置流位置
如果不想修改CreateTar的实现,也可以在拿到返回的流后手动重置位置再返回:
MemoryStream tarStream = TarCreator.CreateTar(toDownload); tarStream.Position = 0; return File(tarStream, MimeTypes.MimeTypeMap.GetMimeType(".tar"), "test.tar");
内容的提问来源于stack exchange,提问作者trinalbadger587
相关产品推荐
相关产品推荐

