2013-03-08 79 views
11

的在ASP.NET的WebAPI的文件,我送一個臨時文件到客戶端。我打開一個流來讀取文件並使用HttpResponseMessage上的StreamContent。一旦客戶機接收到該文件,我想一旦客戶端臨危文件來刪除臨時文件(沒有來自客戶端的任何其它呼叫) ,HttpResponseMessage的Dispose方法被調用&的流也被設置。現在,我想在這一點上刪除臨時文件。如何刪除已發送的StreamContent HttpResponseMessage

一種方法是從HttpResponseMessage類派生一個類,重寫Dispose方法,刪除這個文件&調用基類的dispose方法。 (我還沒有嘗試過,所以不知道,如果這個工程肯定)

我想知道是否有任何更好的方法來實現這一目標。

+1

上述方法似乎工作,但內容所需要的文件被刪除之前佈置(如流的文件仍處於打開狀態)'保護覆蓋無效的Dispose(BOOL處置) { 內容。處置(); FileInfo file = new FileInfo(_localFile); file.Delete(); base.Dispose(處置); }' – 2013-03-08 14:22:53

回答

13

其實your comment幫助解決的問題......我在這裏寫一下吧:

Delete temporary file sent through a StreamContent in ASP.NET Web API HttpResponseMessage

下面是我工作。需要注意的是裏面Dispose調用的順序從您的評論的區別:

public class FileHttpResponseMessage : HttpResponseMessage 
{ 
    private string filePath; 

    public FileHttpResponseMessage(string filePath) 
    { 
     this.filePath = filePath; 
    } 

    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 

     Content.Dispose(); 

     File.Delete(filePath); 
    } 
} 
+2

我想補充,同樣的問題已經被問了一個月這樣的回答後,[這裏](http://stackoverflow.com/questions/20137283/web-api-how-to-detect-when-a-響應已完成發送),並且與此類似。但是不用''HttpResponseMessage'繼承,而是'StreamContent'。我感覺更舒服做那樣的工作,因爲它是有問題(覆蓋較少的行爲)更接近問題,避免'Content.Dispose()顯式調用;' – Chopin 2014-03-22 14:52:18

+0

要非常小心,像這樣的方法。 'Dispose(bool)'方法意味着從Dispose()和finalizer中調用。終結者絕不能拋出。所以你可能想要測試'disposing',並且只有在'disposing'爲true時才調用'File.Delete'。 – 2015-10-07 23:15:46

3

我做到了,通過把文件讀入一個byte []第一,刪除文件,然後返回響應:

 // Read the file into a byte[] so we can delete it before responding 
     byte[] bytes; 
     using (var stream = new FileStream(path, FileMode.Open)) 
     { 
      bytes = new byte[stream.Length]; 
      stream.Read(bytes, 0, (int)stream.Length); 
     } 
     File.Delete(path); 

     HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
     result.Content = new ByteArrayContent(bytes); 
     result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
     result.Content.Headers.Add("content-disposition", "attachment; filename=foo.bar"); 
     return result; 
+1

希望你的文件不是太大。 – 2016-10-20 02:03:27

4

從具有DeleteOnClose選項的FileStream中創建StreamContent。

return new HttpResponseMessage(HttpStatusCode.OK) 
{ 
    Content = new StreamContent(
     new FileStream("myFile.txt", FileMode.Open, 
       FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose) 
    ) 
};