ASP.NET文件下载的几种方法

2010年1月17日 | 标签: ,

当服务器要提供文件下载时,HttpResponse有这么几种方法可以使用。

  1. 用Response.WriteFile,如:
  2. 1
    2
    
    Response.ContentType = "application/octet-stream";
    Response.WriteFile(@"whatever.zip");
  3. 采用aspnet2.0的新方法 Response.TransmitFile,注意此方法将指定的文件直接写入 HTTP 响应输出流,而不在内存中缓冲该文件。如:
  4. 1
    2
    3
    
    Response.ContentType = "application/x-zip-compressed";
    Response.AddHeader("Content-Disposition", "attachment;filename=downloadfilename.zip");
    Response.TransmitFile(@"whatever.zip");

    (假设同文件夹下有个需要下载的文件叫whatever.zip,而用户下载时默认名称为downloadfilename.zip)

  5. 需要注意的是,我们都知道Server.ScriptTimeout 的默认值是90秒,而当我们在web.config中打开调试模式,此值变为30,000,000秒。这也是为什么我在开发时一般不会发现超时问题。当下载大文件时,用Response.WriteFile会使Aspnet_wp.exe缓存了太大空间而导致下载失败。
  6. 这时建议采用文件流形式。如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    
    System.IO.Stream iStream = null;
     
            //以10K为单位缓存:
            byte[] buffer = new Byte[10000];
     
           int length;
     
           long dataToRead;
     
            // 制定文件路径.
            string filepath = @"D:\mybigfile.zip";
     
            //  得到文件名.
            string filename = System.IO.Path.GetFileName(filepath);
     
            try
            {
                // 打开文件.
                iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
                            System.IO.FileAccess.Read, System.IO.FileShare.Read);
     
     
                // 得到文件大小:
                dataToRead = iStream.Length;
     
                Response.ContentType = "application/octet-stream";
                Response.AddHeader("Content-Disposition", "attachment; filename="+filename);
     
                while (dataToRead > 0)
                {
                    //保证客户端连接
                    if (Response.IsClientConnected)
                    {
                       length = iStream.Read(buffer, 0, 10000);
     
                       Response.OutputStream.Write(buffer, 0, length);
     
                        Response.Flush();
     
                        buffer = new Byte[10000];
                        dataToRead = dataToRead - length;
                    }
                    else
                    {
                        //结束循环
                        dataToRead = -1;
                    }
                }
            }
            catch (Exception ex)
            {
                // 出错.
                Response.Write("Error : " + ex.Message);
            }
            finally
            {
                if (iStream != null)
                {
                    //关闭文件
                    iStream.Close();
                }
            }
目前还没有任何评论.