我有一个asp.net网站,允许用户下载大文件--30mb到大约60mb。有时下载工作正常,但在下载完成之前,通常会在某些不同点失败,并显示与服务器的连接已重置的消息。
最初我只是使用Server.TransmitFile但是在读完之后我现在使用下面发布的代码。我还在Page_Init事件中将Server.ScriptTimeout值设置为3600。
private void DownloadFile(string fname, bool forceDownload)
{
string path = MapPath(fname);
string name = Path.GetFileName(path);
string ext = Path.GetExtension(path);
string type = "";
// set known types based on file extension
if (ext != null)
{
switch (ext.ToLower())
{
case ".mp3":
type = "audio/mpeg";
break;
case ".htm":
case ".html":
type = "text/HTML";
break;
case ".txt":
type = "text/plain";
break;
case ".doc":
case ".rtf":
type = "Application/msword";
break;
}
}
if (forceDownload)
{
Response.AppendHeader("content-disposition",
"attachment; filename=" + name.Replace(" ", "_"));
}
if (type != "")
{
Response.ContentType = type;
}
else
{
Response.ContentType = "application/x-msdownload";
}
System.IO.Stream iStream = null;
// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];
// Length of the file:
int length;
// Total bytes to read:
long dataToRead;
try
{
// Open the file.
iStream = new System.IO.FileStream(path, System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.Read);
// Total bytes to read:
dataToRead = iStream.Length;
//Response.ContentType = "application/octet-stream";
//Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
// Read the bytes.
while (dataToRead > 0)
{
// Verify that the client is connected.
if (Response.IsClientConnected)
{
// Read the data in buffer.
length = iStream.Read(buffer, 0, 10000);
// Write the data to the current output stream.
Response.OutputStream.Write(buffer, 0, length);
// Flush the data to the HTML output.
Response.Flush();
buffer = new Byte[10000];
dataToRead = dataToRead - length;
}
else
{
//prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}
catch (Exception ex)
{
// Trap the error, if any.
Response.Write("Error : " + ex.Message);
}
finally
{
if (iStream != null)
{
//Close the file.
iStream.Close();
}
Response.Close();
}
}
答案 0 :(得分:2)
威尔
<configuration>
<system.web>
<httpRuntime executionTimeout="3600"/>
</system.web>
</configuration>
帮助什么?
写入数据的内部循环似乎有点复杂,我至少会将其更改为:
int length;
while( Response.IsClientConnected &&
(length=iStream.Read(buffer,0,buffer.Length))>0 )
{
Response.OutputStream.Write(buffer,0,length);
Response.Flush();
}
没有必要在循环中每次重新分配缓冲区,只需在将其写入输出后重新使用它。
进一步的改进是使用异步IO,但那是另一天。
答案 1 :(得分:2)
当我使用FileUpload Control时,我遇到了类似的问题,我上传的文件大小&gt; 4MB。我曾经得到'连接已重置'错误页面。这是我为解决问题而采取的步骤:
转到web.config文件并设置适合您希望上传的文件类型的大小限制。默认大小限制为4096千字节(KB)或4兆字节(MB)。您可以通过设置httpRuntime元素的maxRequestLength属性来允许上载更大的文件。要增加整个应用程序的最大允许文件大小,请在Web.config文件中设置maxRequestLength属性。
例如,允许使用10MB(10240 KB)文件。我使用(使用'&lt;'和']'替换'''与'&gt;'替换''')
[配置]
[System.Web程序]
[httpRuntime maxRequestLength =“10240”/]
[/system.web]
[/配置]
答案 2 :(得分:0)
此问题的最终解决方法是在web.config文件中进行修改。我只需将sessionState mode =“InProc”更改为sessionState mode =“StateServer”。
答案 3 :(得分:0)
最终为我工作的是做一个Response.End并且还在文件流中使用using语句。这是我的代码:
public partial class ssl_Report_StreamReport : BaseReportPage
{
protected void Page_Load(object sender, EventArgs e)
{
//Get the parameters
string reportName = Utils.ParseStringRequest(Request, "reportName") ?? string.Empty;
string reportGuid = Session["reportGuid"].ToString();
string path = Path.Combine(ReportPath(), Utils.GetSessionReportName(reportName, reportGuid));
using (var fileStream = File.Open(path, FileMode.Open))
{
Response.ClearHeaders();
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + reportName + "\"");
Response.AddHeader("Content-Length", fileStream.Length.ToString(CultureInfo.InvariantCulture));
StreamHelper.CopyStream(fileStream, Response.OutputStream);
Response.Flush();
Response.End();
}
ReportProcessor.ClearReport(Session.SessionID, path);
}
}
public static class StreamHelper
{
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
}