我有一個類使用外部進程來創建一個文件,並作爲下載結果返回,此時我想從服務器上刪除文件。我通常喜歡避免臨時的磁盤文件,但在這種情況下是不可避免的。有沒有一種乾淨的方式來返回FilePathResult並在之後刪除磁盤上的文件?
我最初嘗試此使用Dispose方法來實現:
public class SetupFile : IDisposable
{
/// <summary>Local file path</summary>
public string LocalFilePath { get; set; }
/// <summary>Filename to present to user</summary>
public string DownloadFilename { get; set; }
public void Dispose()
{
System.IO.File.Delete(LocalFile);
}
}
控制器代碼創建並在此文件進行操作,然後返回結果作爲FilePathResult
:
public class DownloadController : Controller
{
public SetupFileGenerator Generator { get; set; }
public DigitalSignatureTool Signer { get; set; }
[HttpPost, Route("/download")]
public ActionResult Download(InstallParams params)
{
using (SetupFile file = Generator.Generate(params)) {
{
Signer.Sign(file.LocalFilePath); // note: requires a local path!
return new FilePathResult(file.LocalFilePath, "application/octet-stream")
{
FileDownloadName = file.DownloadFilename
};
}
}
}
(請注意,Generator
和Signer
正通過依賴注入被插入控制器,並保持c oncerns我不想要SetupFileGenerator
取決於DigitalSignatureTool
。重要的是,我需要Signer.Sign
的磁盤上的文件運行 - 因此Generator.Generate()
不能只是返回一個流)。
這裏的問題是FilePathResult
只在its WriteFile()
method後來在處理管道中調用時才發送文件,這意味着我的SetupFile.Dispose()
方法已被調用。
我想我的下一個步驟是做兩件事情之一:
- 實現從
FilePathResult
派生又是一個新的類刪除該文件它發送 - 重構我的代碼後認爲與其
SetupFile
具有財產string LocalFilePath
,它有MemoryStream FileContents
然而,這似乎是它將是一個相當常見的模式,所以在我重新開始研究之前,是否有最佳實踐?有什麼要特別留意的?
應該將兩個過程分開,因爲文件管理可以是一個皮塔。有時文件會被鎖定,導致您不想在這裏管理的問題。你應該把這個管理放到一個簡單的服務中,只要你喜歡就可以運行。 – phillip 2015-02-23 20:49:19
你可以使用從'MemoryStream'繼承的一個類來覆蓋'Dispose()'方法嗎? – 2015-02-23 20:52:45
@phillip好點:可能有一些原因可能會導致失敗,這需要週期性的帶外清理操作。但是這也需要考慮到它不能刪除正在使用的文件(例如,當前正在下載的文件)。可以使用。 – gregmac 2015-02-23 21:01:59