使数据库大字段的 Server Side ASP.Net Web/Http 下载,支持 FlashGet (Client) 断点续传多线程下载

今天看了 bestcomy 的
例程:ASP.NET实现从MSSQL中分块断点续传下载image字段内容
http://www.cnblogs.com/bestcomy/archive/2005/05/08/150815.html

不过代码复杂了些!

这里请大家参阅:
ms-help://MS.NETFrameworkSDKv1.1.CHS/cpref/html/frlrfSystemDataCommandBehaviorClassTopic.htm
注意:
SequentialAccess
 提供一种方法,以便 DataReader 处理包含带有大二进制值的列的行。SequentialAccess 不是加载整行,而是使 DataReader 将数据作为流来加载。然后可以使用 GetBytes 或 GetChars 方法来指定开始读取操作的字节位置以及正在返回的数据的有限的缓冲区大小。
当指定 SequentialAccess 时,尽管无需读取每个列,但是需要按照列的返回顺序读取它们。一旦已经读过返回的数据流中某个位置的内容,就不能再从 DataReader 中读取该位置或该位置之前的数据。当使用 OleDbDataReader 时,可重新读取当前列的值,直到读过它。当使用 SqlDataReader 时,一次只能读取一个列值。

关于如何支持 FlashGet 断点续传多线程下载请参阅:
 http://blog.csdn.net/playyuer/archive/2004/08/02/58281.aspx
 http://blog.csdn.net/playyuer/archive/2004/08/02/58430.aspx

因此代码可以更简单些,支持 Oracle 也不会太难:
1. BlobDownload.aspx 前代码(HTML)

<%@ Page language="c#" Codebehind="BlobDownload.aspx.cs" AutoEventWireup="false" Inherits="BlobDownload" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
    
<HEAD>
        
<title>WebForm1</title>
        
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
        
<meta name="CODE_LANGUAGE" Content="C#">
        
<meta name="vs_defaultClientScript" content="JavaScript">
        
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
    
</HEAD>
    
<body MS_POSITIONING="GridLayout">
        
<form id="Form1" method="post" runat="server">
        
</form>
    
</body>
</HTML>


2. BlobDownload.aspx 后代码 BlobDownload.aspx.cs

using System;
using System.Data;
using System.Data.SqlClient;

//namespace Microshaoft
//{
    /// <summary>
    
/// WebForm1 的摘要说明。
    
/// </summary>

    public class BlobDownload : System.Web.UI.Page
    
{
        
private void Page_Load(object sender, System.EventArgs e)
        
{
            
//Sql*** 以后换成 Oracle*** 估计就可以实现支持 Oracle 了
            SqlConnection scn = new SqlConnection(@"Data Source=SERVER\PSQLKE;Initial Catalog=northwind;user id=sa");
            
//字段顺序不要错
            SqlCommand scmd = new SqlCommand("SELECT categoryName,DataLength(Picture),Picture FROM Categories where categoryName='Test'", scn);
            scn.Open();
            SqlDataReader sdr 
= scmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult);
            
if (sdr.Read()) //只读取一条记录
            {
                
try
                
{
                    
string FileName = sdr.GetString(0);//FileName
                    Response.AddHeader("Content-Disposition""attachment; filename=" + FileName + ".rar");

                    
int size = 64 * 1024//buffer size
                    byte[] bytes = new byte[size];

                    
long l = sdr.GetInt32(1);//DataLength
                    long p = 0;
                    Response.AddHeader(
"Accept-Ranges""bytes");
                    
if (Request.Headers["Range"!= null)
                    
{
                        Response.StatusCode 
= 206;
                        p 
= long.Parse( Request.Headers["Range"].Replace("bytes=","").Replace("-",""));
                    }

                    Response.AddHeader(
"Content-Length", ((long)(l - p)).ToString()); 
                    
if (p != 0)
                    
{
                        
//不是从最开始下载,
                        
//响应的格式是:
                        
//Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
                        Response.AddHeader("Content-Range","bytes " + p.ToString() + "-" + ((long)(l - p)).ToString() + "/" + l.ToString());
                    }

                    
long r = sdr.GetBytes(2, p, bytes, 0, bytes.Length);
                    
while (r == size)
                    
{
                        Response.OutputStream.Write(bytes,
0,(int) r);
                        p 
+= size;
                        r 
= sdr.GetBytes(2, p, bytes, 0, size);
                    }

                    Response.OutputStream.Write(bytes,
0,(int) r);
                }

                
finally
                
{
                    sdr.Close();
                    scn.Close();
                    Response.End();
                }

            }

            
else
            
{
                Response.Write(
"Error: can not download your request");
            }

        }


        
#region Web 窗体设计器生成的代码
        
override protected void OnInit(EventArgs e)
        
{
            
//
            
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
            
//
            InitializeComponent();
            
base.OnInit(e);
        }

        
        
/// <summary>
        
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
        
/// 此方法的内容。
        
/// </summary>

        private void InitializeComponent()
        
{
            
this.Load += new System.EventHandler(this.Page_Load);
        }

        
#endregion

    }

//}


另外还有一个:
.Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (第2版) (C# DIY HttpWebClient)
http://www.cnblogs.com/microshaoft/archive/2005/03/21/122645.aspx

经测试也已可成功下载,如下测试URL:
http://localhost/myasp.net/blobdownload.aspx

posted @ 2005-05-08 19:46  于斯人也  阅读(2477)  评论(4编辑  收藏  举报