ASP .NET核
MVC控制器-使用FileStream并返回FileStreamResult从服务器存储中下载文件
public IActionResult Download(string path, string fileName)
{
var fileStream = System.IO.File.OpenRead(path);
return File(fileStream, "application/force-download", fileName);
}一切正常,但是一旦用户在下载完成之前取消了下载,则控制器中处理此文件的其他操作(删除文件、重命名文件)不能工作,因为:进程不能访问该文件,因为它正在被另一个进程使用。
当文件下载完成时,FileStream会自动释放,但由于某些原因,它不会在用户手动终止下载时终止。
我必须重新启动web应用程序=>,使用该文件的程序是IISExpress。
如果用户手动结束下载,请有人知道如何释放流吗?
编辑:
FileStream stream = null;
try
{
using (stream = System.IO.File.OpenRead(path))
{
return File(stream, "application/force-download", fileName);
}
}返回FileStreamResult,后试图结束流的代码我知道它不能工作,因为return File (stream, contentType, fileName)之后它会立即跳转到块,最后和流关闭,所以下载不会启动,因为流关闭了
发布于 2022-04-26 13:50:32
看来,来源的FileStreamResult类显示它不支持取消。如果需要的话,您将需要实现自己的。例如(未经测试,只是想象)
using System.IO;
namespace System.Web.Mvc
{
public class CancellableFileStreamResult : FileResult
{
// default buffer size as defined in BufferedStream type
private const int BufferSize = 0x1000;
private readonly CancellationToken _cancellationToken;
public CancellableFileStreamResult(Stream fileStream, string contentType,
CancellationToken cancellationToken)
: base(contentType)
{
if (fileStream == null)
{
throw new ArgumentNullException("fileStream");
}
FileStream = fileStream;
_cancellationToken = cancellationToken;
}
public Stream FileStream { get; private set; }
protected override void WriteFile(HttpResponseBase response)
{
// grab chunks of data and write to the output stream
Stream outputStream = response.OutputStream;
using (FileStream)
{
byte[] buffer = new byte[BufferSize];
while (!_cancellationToken.IsCancellationRequested)
{
int bytesRead = FileStream.Read(buffer, 0, BufferSize);
if (bytesRead == 0)
{
// no more data
break;
}
outputStream.Write(buffer, 0, bytesRead);
}
}
}
}
}然后你可以像这样使用它
public IActionResult Download(string path, string fileName, CancellationToken cancellationToken)
{
var fileStream = System.IO.File.OpenRead(path);
var result = new CancellableFileStreamResult(
fileStream, "application/force-download", cancellationToken);
result.FileDownloadName = fileName;
return result;
}再说一遍,我这不是测试,只是想象。也许这不起作用,因为动作已经完成了,所以不能再取消了。
编辑:上面对ASP.net框架的回答是“想象的”。ASP.net核心有一个完全不同的底层框架:在.net核心中,动作由和执行器处理,如来源所示。这最终会叫FileResultHelper。在这里您可以看到StreamCopyOperation是与cancellationToken context.RequestAborted一起调用的。即,取消在.net核心中的位置。
最大的问题是:为什么在您的情况下请求不被中止。
https://stackoverflow.com/questions/72011337
复制相似问题