[英]How to delete a file after it was streamed in ASP.NET Core
我想在返回表單操作后刪除一個臨時文件。 我如何使用ASP.NET Core實現這一目標:
public IActionResult Download(long id)
{
var file = "C:/temp/tempfile.zip";
var fileName = "file.zip;
return this.PhysicalFile(file, "application/zip", fileName);
// I Would like to have File.Delete(file) here !!
}
該文件太大,無法使用內存流返回。
File()或PhysicalFile()返回一個FileResult
派生類, FileResult
將處理委托給執行程序服務。 PhysicalFileResult
的ExecuteResultAsync方法調用:
var executor = context.HttpContext.RequestServices
.GetRequiredService<IActionResultExecutor<PhysicalFileResult>>();
return executor.ExecuteAsync(context, this);
所有其他基於FileResult的類以類似的方式工作。
PhysicalFileResultExecutor類實質上將文件的內容寫入Response流。
一個快速而骯臟的解決方案是創建自己的基於PhysicalFileResult
的類,該類委托給PhysicalFileResultExecutor但是在執行程序完成后刪除文件:
public class TempPhysicalFileResult : PhysicalFileResult
{
public TempPhysicalFileResult(string fileName, string contentType)
: base(fileName, contentType) { }
public TempPhysicalFileResult(string fileName, MediaTypeHeaderValue contentType)
: base(fileName, contentType) { }
public override async Task ExecuteResultAsync(ActionContext context)
{
await base.ExecuteResultAsync(context);
File.Delete(FileName);
}
}
您可以創建並返回TempPhysicalFileResult
,而不是調用PhysicalFile()
來創建PhysicalFileResult
,例如:
return new TempPhysicalFileResult(file, "application/zip"){FileDownloadName=fileName};
這與PhysicalFile()的作用相同:
[NonAction]
public virtual PhysicalFileResult PhysicalFile(
string physicalPath,
string contentType,
string fileDownloadName)
=> new PhysicalFileResult(physicalPath, contentType) { FileDownloadName = fileDownloadName };
一個更復雜的解決方案是創建一個自定義執行程序,負責處理壓縮和清理文件,使動作代碼保持清除結果格式代碼
您可以加載文件的內容。 刪除文件並發送內容作為響應。 在MVC中,您可以返回一個文件作為響應。 檢查下面的代碼段
public FileResult Download()
{
var fileName = $"client-file-name.ext";
var filepath = $"filepath";
byte[] fileBytes = System.IO.File.ReadAllBytes(filepath);
//delete file here
return File(fileBytes, "application/x-msdownload", fileName);
}
由於文件很大,所以解決方案是在請求旁邊發送令牌(如guid)。 只有在下載完成后才能刪除該文件(否則您可能會丟失該文件)。 因此,使用該令牌,客戶端將使用上述令牌發出新請求。 因此,您將知道下載成功,並且您可以繼續刪除該文件。
我建議使用Dictionary將令牌映射到文件。
由於您很容易丟失文件,因此刪除一個請求似乎是一種不好的做法。
此外,您可以使用Henk Mollema答案確保所有文件都定期清除,如果這是您要實現的目標。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.