Asp.NET大文件上传组件开发总结(二)---提取文件内容

不知地震什么时候结束,为了给老婆小孩守夜,看来还不能睡,那就把第二篇也写了吧,只是不知对大家有没有用哟。

为了提供文件内容,我们需要首先需确定客户请求中发送的有文件内容,然后确定文件内容的位置。这部分对应的代码如下:

 1 None.gif HttpApplication app  =  sender  as  HttpApplication;
 2 None.gif            HttpWorkerRequest request  =  GetWorkerRequest(app.Context);
 3 None.gif            
 4 None.gif             if  ( ! IsUploadRequest(app.Request))  return // 不是文件上传,则退出
 5 None.gif             
 6 None.gif             string  sContentType  =  app.Request.ContentType.ToLower();
 7 None.gif             byte [] arrBoundary  =  GetMultipartBoundary(sContentType);
 8 None.gif             int  ContentLength  =  app.Request.ContentLength;  // 信息体的总长度
 9 None.gif
10 None.gif            DataReader dataReader  =   new  DataReader(app.Context.Request.ContentEncoding, arrBoundary);
11 None.gif            DateTime startDate  =  DateTime.Now;
12 None.gif             byte [] arrBuffer  =  request.GetPreloadedEntityBody();
13 None.gif             if  (arrBuffer  ==   null )
14 ExpandedBlockStart.gifContractedBlock.gif             dot.gif {
15InBlock.gif                arrBuffer = new Byte[0];
16InBlock.gif                tempFile.Close();
17InBlock.gif                return//没有读取到信息体
18ExpandedBlockEnd.gif            }

19 None.gif             else
20 ExpandedBlockStart.gifContractedBlock.gif             dot.gif {
21InBlock.gif             dot.gif这里是对文件内容的处理
22ExpandedBlockEnd.gif            }

上面的代码中,我们先获取Asp.NET对客户端请求的处理对象HttpWorkerRequest,然后根据这个对象的ContentType属性是否为multipart/form-data来确定对应的请求是否有上传文件,如果没有上传文件,就不处理此请求,以提高处理效率。这样处理的依据是,在有文件上传的HTML Form中,对应的enctype属性为multipart/form-data。这样就解决了确定客户端请求中是否发送有文件内容。
要确定文件的内容位置,为此我们需要使用Reflector工具反编译 System.Web.dllHttpRequest的代码,可以发现有一个GetEntireRawContent方法,这个方法里,调用了HttpWorkerRequest对的GetPreloadedEntityBody方法来获取数据,可喜的是,这个方法是Public的,所以我们也可以直接调此方法来获取客户端发送的数据。
获取数据后,我们可以将这些数据写入到一个文件中,这些数据是byte[]类型的,在写入文件时,因为Http协议是基于文本的,所以我们可以采用System.Text.Encoding.GetString方法,将这些字节数组编码成字符串,我这里的编码采用ASCII,只是这样请求中的中文就成了乱码。这样就可以获取请求的内容的文体格式,以方便我们分析(在代码中,这个写文件的功能我已去除,因为这里写全部请求内容只是用于分析使用,请参见第一篇文章中我列出的请求内容示例)。
通过分析这些请求内容,我们可以发现:每个页面控件,均可以在这里找到对应的内容,两个控件内容间是用字符串“-----------------------------7d81e441d025c”分隔的。同时在我们反编译 System.Web.dllHttpRequest的代码时,也可以发有GetMultipartBoundary这个方法,这个方法我们可以从字面意思得知是取分隔标识。我们把这个方法提取出来:
 1 None.gif private   byte [] GetMultipartBoundary()
 2 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 3InBlock.gif    string attributeFromHeader = GetAttributeFromHeader(this.ContentType, "boundary");
 4InBlock.gif    if (attributeFromHeader == null)
 5ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 6InBlock.gif        return null;
 7ExpandedSubBlockEnd.gif    }

 8InBlock.gif    attributeFromHeader = "--" + attributeFromHeader;
 9InBlock.gif    return Encoding.ASCII.GetBytes(attributeFromHeader.ToCharArray());
10ExpandedBlockEnd.gif}


然后我们采用这个方法,就可以从请求的内容中提取出类似“-----------------------------7d81e441d025c”这样的字符串。这样,我们就可以分隔页面内不同控件的内容了。
最后,我们分析文件上传控件的内容:

Content - Disposition: form - data; name = " file1 " ; filename = " C:\Documents and Settings\Administrator\??????\componentart.web.ui.rar "
Content
- Type: application / x - rar - compressed

Rar
!   ?? s


我们可以发现,文件上传控件有一个filename属性,然后,下一行指定文件的MIME类型,随后这个空白行,在空白行下面,直到下一处类似“-----------------------------7d81e441d025c”标志字符串间,就是客户端发送的文件内容。我们只需把这些内容写入到服务器文件中即可。

这里,文件内容的提取的问题就可以解决了。在提取文件内容时,对处理标志字符串时需要特别处理,防止标志字符分别读取到两个缓冲区中,所以这部分代码还是比较多的,具体请参看源代码中的DataReader类。

第二篇就写到这,实在是太困了,后面的等一下再写吧!

转载于:https://www.cnblogs.com/bashan/archive/2008/05/14/1196057.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值