我有以下用于下载大文件的代码。它从文件流读取并写入Response.Outputstream。
它似乎正在工作,即该文件似乎正在下载(奇怪的是,实际上似乎正在下载更多文件),但最终失败。 Chrome给出“网络错误”,IE显示“(已中止)”
[OperationContract]
[WebInvoke(UriTemplate = "/f/{key}", Method = "GET")]
public void LargeFileDownload(string key)
{
var identifier = PublicIdentifier.FromString(key, true);
if (identifier.Type == PublicIdentifier.IdentifierType.DocumentDownload)
{
Document doc = Business.Documents.GetById(Application.SystemUser, identifier.Id);
string tempName = Path.GetTempPath() + doc.OriginalFileName;
int bufferSize = 8192;
FileStream fstream = new FileStream(tempName, FileMode.Open, FileAccess.Read);
long fileSize = fstream.Length;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ContentType = doc.ContentType;
string contentDisposition = string.Format("{0};filename={1}{2}", "attachment", doc.Name.Replace(" ", "_"), Path.GetExtension(doc.OriginalFileName));
HttpContext.Current.Response.AddHeader("Content-Disposition", contentDisposition);
HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
WebOperationContext.Current.OutgoingResponse.ContentType = doc.ContentType;
try
{
byte[] buffer = new byte[bufferSize];
int bytesRead = 0;
while ((bytesRead = fstream.Read(buffer, 0, bufferSize)) > 0)
{
HttpContext.Current.Response.OutputStream.Write(buffer, 0, bufferSize);
HttpContext.Current.Response.Flush();
}
}
finally
{
if (fstream != null)
fstream.Close();
//File.Delete(tempName);
}
}
}
更新的代码:-
[OperationContract]
[WebInvoke(UriTemplate = "/f/{key}", Method = "GET")]
public void LargeFileDownload(string key)
{
var identifier = PublicIdentifier.FromString(key, true);
if (identifier.Type == PublicIdentifier.IdentifierType.DocumentDownload)
{
Document doc = Business.Documents.GetById(Application.SystemUser, identifier.Id);
string tempName = Path.GetTempPath() + doc.OriginalFileName;
int bufferSize = 8192;
FileStream fstream = new FileStream(tempName, FileMode.Open, FileAccess.Read);
long fileSize = fstream.Length;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ContentType = "application/octet-stream";
string contentDisposition = string.Format("{0};filename={1}{2}", "attachment", doc.Name.Replace(" ", "_"), Path.GetExtension(doc.OriginalFileName));
HttpContext.Current.Response.AddHeader("Content-Disposition", contentDisposition);
HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
HttpContext.Current.Response.ContentType = "application/octet-stream";
try
{
byte[] buffer = new byte[bufferSize];
int bytesRead = 0;
while ((bytesRead = fstream.Read(buffer, 0, bufferSize)) > 0)
{
HttpContext.Current.Response.OutputStream.Write(buffer, 0, bytesRead);
HttpContext.Current.Response.Flush();
}
}
finally
{
if (fstream != null)
fstream.Close();
//File.Delete(tempName);
}
}
}
提琴手原始:-
HTTP/1.1 504 Fiddler - Receive Failure
Date: Wed, 17 Oct 2018 11:53:09 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Cache-Control: no-cache, must-revalidate
Timestamp: 12:53:09.099
[Fiddler] ReadResponse() failed: The server did not return a complete response for this request. Server returned 13,912,938 bytes.
答案 0 :(得分:0)
您正确设置了Content-Length
,浏览器假定该值为true。但是由于这个错误,您正在发送更多数据(这是垃圾):
HttpContext.Current.Response.OutputStream.Write(buffer, 0, bufferSize);
这不应该是bufferSize
,而应该是bytesRead
。这会导致协议错误,导致浏览器中止其处理。
复制循环可能应该由对TransmitFile
的调用或至少由Stream.Copy
的调用来代替。