Power by DMForum.NET!
RSS | ATOM | WAP
DMForum.NET 官方支持讨论区 > 技术区 > WEB开发技术

浏览主题:??????????????网招???京京???网招???

主题:??????????????网招???京京???网招???
devms
管理员
8级
等级:黄金骑士
发帖:3934
金钱:4064
经验:25679
积分:2
性别:帅哥
状态:离线
注册:2006-7-29 23:37:00
二进制数据读取控制。  
[ 2008-2-16 2:41:06 ]

c# 程序代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace DEVMS.COM.DMForum.Kernel
{
             
/// <summary>
             
/// 二进制数据读取控制。
             
/// </summary>
             //一个boundary条分隔一个文件/表单数据,每次依次取一字节数据,取到换行时结束,随后判断此行
             
//每次遇到boundary行即是开始新数据表单
             public class HttpBinaryReader
             {
                             
private string _boundary;
                             
private string _tempdirectory;
                             
private string _hash;
                             
private int _index;
                             
private CheckAccessDelegate _cad;
                             
private HttpWorkerRequest _request;
                             
/// <summary>
                             
/// 初始化二进制数据读取控制。
                             
/// </summary>
                             public HttpBinaryReader()
                             {
                             }
                             
/// <summary>
                             
/// 初始化二进制数据读取控制。
                             
/// </summary>
                             
/// <param name="boundary">分隔块字符串值。</param>
                             public HttpBinaryReader( string boundary, string tempdirectory, string hash,CheckAccessDelegate cad,HttpWorkerRequest request )
                             {
                                             
this._boundary = boundary;
                                             
this._tempdirectory = tempdirectory;
                                             
this._hash = hash;
                                             
this._cad = cad;
                                             
this._request = request;
                             }
                             
public string getString( byte[] b )
                             {
                                             
string t = DEVMS.COM.API.BaseObject.String( b );
                                             
if ( t.Length < 2 ) return t;
                                             t 
= t.Substring( 1 );
                                             
return t.Substring( 0, t.Length - 1 );
                             }
                             
public void output( string mess )
                             {
                                             System.Web.HttpContext.Current.Response.Write( mess 
+ "<br/>" );
                                             System.Web.HttpContext.Current.Response.Flush();
                             }
                             
/// <summary>
                             
/// 读取每段数据的头信息,返回除头信息外的数据正文。
                             
/// </summary>
                             
/// <returns></returns>
                             public string ReadBlockHead( string data, HttpBlockInfo hbinfo )
                             {
                                             
string t = data;
                                             
int ts = t.IndexOf( "\r\nContent-Disposition: form-data;" ) + "\r\nContent-Disposition: form-data;".Length;
                                             
//获取第一行头信息文本
                                             string cdt = t.Substring( ts );
                                             
string scdt = cdt.Substring( 0, cdt.IndexOf( "\r\n" ) );
                                             
//按;号分隔
                                             string[] cds = scdt.Split( ";".ToCharArray() );
                                             
//遍历每项
                                             foreach ( string cd in cds )
                                             {
                                                             
//分开=号两旁的名称和值
                                                             string[] cs = cd.Split( "=".ToCharArray() );
                                                             
//如果不是键=值形式则跳到下一项
                                                             if ( cs.Length < 2 ) continue;
                                                             
//如果键名是name,那么代表此项是表单域名称,将值赋予块信息对象的表单域名称属性
                                                             if ( cs[0].Trim() == "name" )
                                                             {
                                                                             hbinfo.InputName 
= cs[1].Trim().Replace( "\"""" );
                                                             }
                                                             
//如果键名不是name,那么则判断此项是文件域附加原文件路径信息,将值赋予块信息对象的源文件路径属性
                                                             
//同时,则证明此段数据是文件数据,那么应将当前系统文件索引递增1。以区别上一文件数据。
                                                             else
                                                             {
                                                                             hbinfo.SourceFile 
= cs[1].Trim().Replace("\"","");
                                                                             
this._index += 1;
                                                             }
                                             }
                                             
//将第一行后的字符进行处理
                                             
//取得第二行的数据
                                             cdt = cdt.Substring( cdt.IndexOf( "\r\n" ) + 2 );
                                             scdt 
= cdt.Substring( 0, cdt.IndexOf( "\r\n" ) );
                                             
//按:号分开
                                             cds = scdt.Split( ":".ToCharArray() );
                                             
//如果不是键:值形式或者键名不等于Content-Type的话,则认为此段没有第二信息行,则直接跳过一个回车换行后将指针置于正文数据头
                                             if ( cds.Length == 2 && cds[0== "Content-Type" )
                                             {
                                                             
//如果是键:值形式以及键名等于Content-Type的话,则读取它的值并赋值给块信息对象的数据流内容类型属性,然后跳过两个回车换行后将指针置于正文数据头
                                                             hbinfo.ContentType = cds[1].Trim();
                                                             cdt 
= cdt.Substring( cdt.IndexOf( "\r\n\r\n" ) + 4 );
                                             }
                                             
else
                                             {
                                                             cdt 
= cdt.Substring( cdt.IndexOf( "\r\n" ) + 2 );
                                             }
                                             
//此时的cdt即正文数据的string表现形式,把它返回
                                             return cdt;
                             }
                             
public byte[] copy( byte[] data, int index, int count )
                             {
                                             
byte[] b = new byte[count];
                                             
if ( index + count > data.Length ) return b;
                                             
for ( int i = index; i < index + count; i++ )
                                             {
                                                             b[i 
- index] = data[i];
                                             }
                                             
return b;
                             }
                             
public bool comBytes( byte[] d1, byte[] d2 )
                             {
                                             
if ( d1.Length != d2.Length ) return false;
                                             
for ( int i = 0; i < d1.Length; i++ )
                                             {
                                                             
if ( d1[i] != d2[i] ) return false;
                                             }
                                             
return true;
                             }
                             
public int indexOfBytes( string str, byte[] data )
                             {
                                             
byte[] s = System.Text.Encoding.Default.GetBytes( str );
                                             
for ( int i = 0; i < data.Length; i++ )
                                             {
                                                             
if ( data[i] == s[0] )
                                                             {
                                                                             
byte[] temp = copy( data, i, s.Length );
                                                                             
if ( comBytes( temp, s ) )
                                                                             {
                                                                                             
return i;
                                                                             }
                                                             }
                                             }
                                             
return -1;
                             }
                             
public string getstr( byte[] b )
                             {
                                             
return DEVMS.COM.API.BaseObject.String( b );
                             }
                             
public byte[] ReadFile( ref byte[] data )
                             {
                                             
int s = indexOfBytes( "--" + this._boundary, data );
                                             
if ( s < 0 ) return data;
                                             
byte[] b;
                                             
byte[] c;
                                             
if ( s > 0 )
                                             {
                                                             b 
= copy( data, 0, s );
                                                             c 
= copy( data, s, data.Length - s );
                                             }
                                             
else
                                             {
                                                             
byte[] t = copy( data, s + ( "--" + this._boundary ).Length, data.Length - s - ( "--" + this._boundary ).Length );
                                                             s 
= indexOfBytes( "--" + this._boundary, t );
                                                             
if ( s < 0 ) s = t.Length;
                                                             b 
= copy( t, 0, s );
                                                             c 
= copy( t, s, t.Length - s );
                                             }
                                             s 
= indexOfBytes( "\r\nContent-Type:", b );
                                             
if ( s > 0 )
                                             {
                                                             s 
= indexOfBytes( "\r\n\r\n", b );
                                                             
if ( s > 0 )
                                                             {
                                                                             
return copy( b, s + 4, b.Length - s - 4 );
                                                             }
                                             }
                                             
else
                                             {
                                                             
if ( indexOfBytes( "\r\nContent-Disposition: form-data;", b ) >= 0 )
                                                             {
                                                                             b 
= ReadFile( ref c );
                                                             }
                                             }
                                             
return b;
                             }

                             
public string ReadNextBlock( byte[] data, List<HttpBlockInfo> list, string tempfile,bool end )
                             {
                                             
//按分隔符分开每段数据
                                             byte[] c = data;
                                             
string temp = DEVMS.COM.API.BaseObject.String( data );
                                             
string[] temps = temp.Split( new string[] { "--" + this._boundary }, StringSplitOptions.RemoveEmptyEntries );
                                             
//定义当前文件流对象和块信息对象
                                             System.IO.FileStream stream = null;
                                             HttpBlockInfo hbinfo 
= null;
                                             
string tmpfile = string.Empty;
                                             
//分析每一段数据
                                             foreach ( string tmp in temps )
                                             {
                                                             
//将当前数据段数据保存在一个局部变量
                                                             string t = tmp;
                                                             
//将字节数组形式的数据保存在另一个局部变量
                                                             byte[] tb = DEVMS.COM.API.BaseObject.Bytes( t );

                                                             
if ( t == "--\r\n" )
                                                             {
                                                                             
//全部数据段已经读取分析完毕,指针到了数据流最末尾,结束所有操作
                                                                             return tempfile.Replace( "#N"this._index.ToString() );
                                                             }
                                                             
if ( t.IndexOf( "\r\nContent-Disposition: form-data;" ) == 0 )
                                                             {
                                                                             
//此处为真则代表已经上一次读取已经完全读取了一整段数据,接下来的数据属于另一段了。
                                                                             
//创建一个新的块信息对象。
                                                                             hbinfo = new HttpBlockInfo( string.Empty, string.Empty, string.Empty, string.Empty, string.Empty );

                                                                             
//调用头解析方法读取块信息并取得正文byte[]数据
                                                                             string binstr = this.ReadBlockHead( t, hbinfo );
                                                                             
                                                                             
//调用类型检查函数检查类型合法型
                                                                             this._cad( this._request, hbinfo, this._hash );
                                                                             
//标记线程运行标志
                                                                             
//HttpContext.Current.Application[this._hash] = "UploadThreadRuning";
                                                                             
//读取正文数据
                                                                             byte[] bin = ReadFile( ref c );
                                                                             
//如果此块为文件数据,则添加数据到对应文件
                                                                             if ( hbinfo.SourceFile.Length > 0 )
                                                                             {
                                                                                             
//将全局文件序号递增1
                                                                                             this._index += 1;
                                                                                             
//初始化临时文件路径,文件序号以当前全局文件序号为准
                                                                                             tmpfile = tempfile.Replace( "#N"this._index.ToString() );
                                                                                             
//将正文数据添加到文件中
                                                                                             stream = new System.IO.FileStream( tmpfile, System.IO.FileMode.Append );
                                                                                             
if ( end )
                                                                                             {
                                                                                                             stream.Write( bin, 
0, bin.Length - 2 );
                                                                                             }
                                                                                             
else
                                                                                             {
                                                                                                             stream.Write( bin, 
0, bin.Length );
                                                                                             }
                                                                                             stream.Flush();
                                                                                             stream.Close();
                                                                                             stream.Dispose();
                                                                                             hbinfo.TempFile 
= tmpfile;
                                                                             }
                                                                             
else
                                                                             {
                                                                                             hbinfo.Value 
= binstr;
                                                                             }
                                                                             
//将块信息对象添加到块信息列表中
                                                                     &