zoukankan      html  css  js  c++  java
  • C#实现文件下载

    1,Http 协议中有专门的指令来告知浏览器, 本次响应的是一个需要下载的文件. 格式如下:
    Content-Disposition: attachment;filename=filename.ext
    以上指令即标记此次响应流是附件,且附件文件名为 filename.ext
    注意:
    (1): 中文文件名需要进行URLEncode编码, 否则在IE 6 下会提示是”无法识别的文件”.

    但经实际测试,在Chrome下不进行URLEncode编码, 也能正常显示.

    (2): 文件名不能有空格, 否则也会被认为是”无法识别的文件”.

    (3): [ASP.Net中] 向响应流中添加该指令必须使用 response.AddHeader() 函数; 使用

    response.Header.Add() 则会报错.

    下面是一个实现下载文件功能的函数:

           /// <summary>
            /// 使用微软的TransmitFile下载文件
            /// </summary>
            /// <param name="filePath">服务器相对路径</param>
            public void TransmitFile(string filePath)
            {
                try
                {
                    filePath = Server.MapPath(filePath);
                    if (File.Exists(filePath))
                    {
                        FileInfo info = new FileInfo(filePath);
                        long fileSize = info.Length;
                        HttpContext.Current.Response.Clear();                    
                        
                        //指定Http Mime格式为压缩包
                        HttpContext.Current.Response.ContentType = "application/x-zip-compressed";
                       
                         // Http 协议中有专门的指令来告知浏览器, 本次响应的是一个需要下载的文件. 格式如下:
                        // Content-Disposition: attachment;filename=filename.txt
                        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + Server.UrlEncode(info.FullName));
                        //不指明Content-Length用Flush的话不会显示下载进度   
                        HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
                        HttpContext.Current.Response.TransmitFile(filePath, 0, fileSize);
                        HttpContext.Current.Response.Flush();
                    }
                }
                catch
                { }
                finally
                {
                    HttpContext.Current.Response.Close();
                }
    
            }

    2 下面是使用WriteFile实现下载

            /// <summary>
            /// 使用WriteFile下载文件  
            /// </summary>
            /// <param name="filePath">相对路径</param>
            public void WriteFile(string filePath)
            {
                try
                {
                    filePath = Server.MapPath(filePath);
                    if (File.Exists(filePath))
                    {
                        FileInfo info = new FileInfo(filePath);
                        long fileSize = info.Length;
                        HttpContext.Current.Response.Clear();
                        HttpContext.Current.Response.ContentType = "application/octet-stream";
                        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachement;filename=" + Server.UrlEncode(info.FullName));
                        //指定文件大小   
                        HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
                        HttpContext.Current.Response.WriteFile(filePath, 0, fileSize);
                        HttpContext.Current.Response.Flush();
                    }
                }
                catch
                { }
                finally
                {
                    HttpContext.Current.Response.Close();
                }
            }

    3,下面是分块实现下载:

            /// <summary>
            /// 使用OutputStream.Write分块下载文件  
            /// </summary>
            /// <param name="filePath"></param>
            public void WriteFileBlock(string filePath)
            {
                filePath = Server.MapPath(filePath);
                if (!File.Exists(filePath))
                {
                    return;
                }
                FileInfo info = new FileInfo(filePath);
                //指定块大小   
                long chunkSize = 4096;
                //建立一个4K的缓冲区   
                byte[] buffer = new byte[chunkSize];
                //剩余的字节数   
                long dataToRead = 0;
                FileStream stream = null;
                try
                {
                    //打开文件   
                    stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    
                    dataToRead = stream.Length;
    
                    //添加Http头   
                    HttpContext.Current.Response.ContentType = "application/octet-stream";
                    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachement;filename=" + Server.UrlEncode(info.FullName));
                    HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());
    
                    while (dataToRead > 0)
                    {
                        if (HttpContext.Current.Response.IsClientConnected)
                        {
                            int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize));
                            HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);
                            HttpContext.Current.Response.Flush();
                            HttpContext.Current.Response.Clear();
                            dataToRead -= length;
                        }
                        else
                        {
                            //防止client失去连接   
                            dataToRead = -1;
                        }
                    }
                }
                catch (Exception ex)
                {
                    HttpContext.Current.Response.Write("Error:" + ex.Message);
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                    }
                    HttpContext.Current.Response.Close();
                }
    
            }
  • 相关阅读:
    专利申请流程
    安装Fedora16与Windows7共存双系统
    rpm检查依赖性
    C++中的static函数和extern关键字
    asp.net 浏览服务器文件
    如何用批处理文件写:获取当前日期的前一天
    有一个无效 SelectedValue,因为它不在项目列表中。
    .net 4.0 检测到有潜在危险的 Request.Form 值。
    ckeditor 在C#中使用
    使用任务计划程序自动执行任务
  • 原文地址:https://www.cnblogs.com/wang7/p/2627298.html
Copyright © 2011-2022 走看看