2016-05-03 1 views
4

ユーザーがメソッドのルートを呼び出したときにファイルをダウンロードするWebAPIメソッドに小さな問題があります。Web APIダウンロードロックファイル

方法自体はかなり単純です:予想通り

public HttpResponseMessage Download(string fileId, string extension) 
{ 
    var location = ConfigurationManager.AppSettings["FilesDownloadLocation"]; 
    var path = HttpContext.Current.Server.MapPath(location) + fileId + "." + extension; 

    var result = new HttpResponseMessage(HttpStatusCode.OK); 
    var stream = new FileStream(path, FileMode.Open); 
    result.Content = new StreamContent(stream); 
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
    return result; 
} 

方法は、作品 - 私はそれを呼び出す初めて。ファイルが送信され、ブラウザがファイルのダウンロードを開始します。 D

プロセスがファイル 」にアクセスできません:\ ... \ - 私はどちらか自分のコンピュータまたは他から再び同じURLを呼び出す場合 -

は、しかし、私はというエラーを取得しますApp_Data \ pdfs \ test-file.pdf 'という名前のファイルがあります。別のプロセスで が使用されているためです。

このエラーは、1分程度続いてから、もう一度ファイルをダウンロードできますが、1回だけです。その後、ファイルがロックされるまで1分ほど待たなければなりません。

私のファイルはかなり大きい(100-800 MB)ことに注意してください。

私の方法で何か不足していますか?ストリームのようにファイルがロックされているようです。

感謝:)

答えて

7

それはあなたのファイルは最初のストリームによってロックされているため、あなたはそれが複数のストリームで開くことができるようにするFileShare指定する必要がある。

public HttpResponseMessage Download(string fileId, string extension) 
{ 
    var location = ConfigurationManager.AppSettings["FilesDownloadLocation"]; 
    var path = HttpContext.Current.Server.MapPath(location) + fileId + "." + extension; 

    var result = new HttpResponseMessage(HttpStatusCode.OK); 
    var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); 
    result.Content = new StreamContent(stream); 
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
    return result; 
} 

のように複数の許可ストリームでこのファイルを読み取り専用で開きます。

そのコンストラクタのオーバーロードに関するMSDN documentationを参照してください。

+0

usingステートメントでストリームを宣言すると、ストリームは応答が返される前に破棄され、ダウンロードは失敗します。 –

+0

あなたは生きもののファビアンです!そのような単純な解決策 - 私は盲目的にしか見ていません:) 私はuse-statementについても考えましたが、あなたが言及したように、それはリターンコールの前に処理されるため意味がありません。 ありがとうございました! :) – JBuus

+2

@JBuusようこそ。ファイルストリームは、クライアントがレスポンスの読み込みを完了したときに実際に存在するはずのコンテンツストリームがすぐに破棄されます。 –