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后我試圖結束 Stream 的代碼,我知道它不能作業,因為在它最終return File (stream, contentType, fileName)立即跳轉到塊并且流關閉之后,所以下載不會開始,因為流已關閉
uj5u.com熱心網友回復:
該課程的來源似乎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 core 有一個完全不同的底層框架:在 .net core 中,action 由 executor 處理,如原始碼所示。這最終將呼叫WriteFileAsync. FileResultHelper在那里你可以看到它StreamCopyOperation是用 cancelToken 呼叫的context.RequestAborted。即取消已在.net Core 中到位。
最大的問題是:為什么在您的情況下請求沒有中止。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/466834.html
上一篇:.net核心中的條紋支付結賬
