zoukankan      html  css  js  c++  java
  • ASP.NET实现文件下载的功能

      文件下载是很多网站中含有的常用功能,在ASP.NET中可以使用FileStream类、HttpRequest对象、HttpResponse对象相互结合,实现输出硬盘文件的功能。该方法支持大文件、续传、速度限制、资源占用小。

      FileStream类:MSDN上的解释为,FileStrem类对文件系统上的文件进行读取、写入、打开和关闭操作,并对其他与文件相关的操作系统句柄进行操作,如管道、标准输入和标准输出。读写操作可以指定为同步或异步操作。FileStream 对输入输出进行缓冲,从而提高性能。

      Response对象:ASP.NET网站中对外输出信息流的基础对象实体。

           下面是封装后的代码,如果你不想用封装代码,可以把封装函数取消,相应能数换成实体值就可以。

           /// <summary>
            ///  输出硬盘文件,提供下载 支持大文件、续传、速度限制、资源占用小
            /// </summary>
            /// <param name="_Request">Page.Request对象</param>
            /// <param name="_Response">Page.Response对象</param>
            /// <param name="_fileName">下载文件名</param>
            /// <param name="_fullPath">带文件名下载路径</param>
            /// <param name="_speed">每秒允许下载的字节数</param>
            /// <returns>返回是否成功</returns>
            public static bool ResponseFile(HttpRequest _Request, HttpResponse _Response, string _fileName, string _fullPath, long _speed)
            {
                try
                {
                    FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    BinaryReader br = new BinaryReader(myFile);
                    try
                    {
                        _Response.AddHeader("Accept-Ranges", "bytes");
                        _Response.Buffer = false;
                        long fileLength = myFile.Length;
                        long startBytes = 0;
    
                        int pack = 10240; //10K bytes
                        //int sleep = 200;   //每秒5次   即5*10K bytes每秒
                        int sleep = (int)Math.Floor((double)(1000 * pack / _speed)) + 1;
                        if (_Request.Headers["Range"] != null)
                        {
                            _Response.StatusCode = 206;
                            string[] range = _Request.Headers["Range"].Split(new char[] { '=', '-' });
                            startBytes = Convert.ToInt64(range[1]);
                        }
                        _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                        if (startBytes != 0)
                        {
                            _Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
                        }
                        _Response.AddHeader("Connection", "Keep-Alive");
                        _Response.ContentType = "application/octet-stream";
                        _Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8));
    
                        br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                        int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1;
    
                        for (int i = 0; i < maxCount; i++)
                        {
                            if (_Response.IsClientConnected)
                            {
                                _Response.BinaryWrite(br.ReadBytes(pack));
                                Thread.Sleep(sleep);
                            }
                            else
                            {
                                i = maxCount;
                            }
                        }
                    }
                    catch
                    {
                        return false;
                    }
                    finally
                    {
                        br.Close();
                        myFile.Close();
                    }
                }
                catch
                {
                    return false;
                }
                return true;
            }
            #endregion            
    View Code

      以上代码亲测有效!附上本人测试用的代码(我下载的文件存放在服务器相对路径:down/学习笔记.rar,由于我的文件用于内部使用,故下载速度限制_speed给的很大)

    protected void Button1_Click(object sender, EventArgs e)
        {
           
                string _fileName=“学习笔记.rar";//下载的文件名
                string _fullPath=MapPath("down/")+_fileName;//带全路径文件名
                long _speed=1000000000;//下载速度限制 字节/s
                try
                {
                    FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    BinaryReader br = new BinaryReader(myFile);
                    try
                    {
                        Response.AddHeader("Accept-Ranges", "bytes");
                        Response.Buffer = false;
                        long fileLength = myFile.Length;
                        long startBytes = 0;
    
                        int pack = 10240; //10K bytes
                        //int sleep = 200;   //每秒5次   即5*10K bytes每秒
                        int sleep = (int)Math.Floor((double)(1000 * pack / _speed)) + 1;
                        if (Request.Headers["Range"] != null)
                        {
                            Response.StatusCode = 206;
                            string[] range = Request.Headers["Range"].Split(new char[] { '=', '-' });
                            startBytes = Convert.ToInt64(range[1]);
                        }
                        Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                        if (startBytes != 0)
                        {
                            Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
                        }
                        Response.AddHeader("Connection", "Keep-Alive");
                        Response.ContentType = "application/octet-stream";
                        Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8));
    
                        br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                        int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1;
    
                        for (int i = 0; i < maxCount; i++)
                        {
                            if (Response.IsClientConnected)
                            {
                                Response.BinaryWrite(br.ReadBytes(pack));
                            }
                            else
                            {
                                i = maxCount;
                            }
                        }
                    }
                    catch
                    {
                       
                    }
                    finally
                    {
                        br.Close();
                        myFile.Close();
                    }
                }
                catch
                {
                    
                }
        }
    View Code

       本人较懒,没想去优化代码,能用就行。

  • 相关阅读:
    some tips
    ORA00847: MEMORY_TARGET/MEMORY_MAX_TARGET and LOCK_SGA cannot be set together
    Chapter 01Overview of Oracle 9i Database Perfomrmance Tuning
    Chapter 02Diagnostic and Tuning Tools
    变量与常用符号
    Chapter 18Tuning the Operating System
    标准输入输出
    Trace files
    DBADeveloped Tools
    Chapter 03Database Configuration and IO Issues
  • 原文地址:https://www.cnblogs.com/wendcn/p/12782325.html
Copyright © 2011-2022 走看看