2008-10-09 69 views
3

我有一個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

此問題的最終解決方案是在web.config文件中進行修改。我只需要將sessionState mode =「InProc」更改爲sessionState mode =「StateServer」。

+0

爲什麼?你能解釋一下原因嗎? – 2014-06-16 07:19:19

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,但那是另一天。

+0

更改執行時間不適用於我。 – 2012-10-11 13:54:30

2

我在使用FileUpload Control時遇到了類似的問題,而且我上傳的文件大小大於4MB。我曾經得到'連接被重置'的錯誤頁面。我按照以下步驟解決問題:

轉到web.config文件並設置適合您希望上載的文件類型的大小限制。默認大小限制是4096千字節(KB)或4兆字節(MB)。您可以通過設置httpRuntime元素的maxRequestLength屬性來允許更大的文件上傳。要增加整個應用程序的最大允許文件大小,請在Web.config文件中設置maxRequestLength屬性。

例如以允許10MB(10240 KB)file..I使用(REPLACE '[' 與 '<' 和 ']' 與 '>')

[配置]
[System.Web程序]
[的httpRuntime的maxRequestLength = 「10240」/]
[/system.web]
[/配置]

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); 
     } 
    } 
}