文件上传、下载

moses_78 2002-02-19 10:26:39
将客户端的文件上传到服务器,以文件形式存储。浏览时左键打开、右键下载。急!!!!
...全文
90 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
lutaiyk 2002-02-19
  • 打赏
  • 举报
回复
直接用别人的组件比较省事。有挺多的。
xuchu 2002-02-19
  • 打赏
  • 举报
回复
用VB6做一个简单的文件上传组件(一)
2001:8:16

用VB6做一个简单的文件上传组件(一)

  来源:chinaasp
  作者: songbird

  最近在单位做的一个项目里需要有文件上传的功能,正好手头一本书的附赠光盘里有一个上传组件,心中大喜。可惜随之便发现这是一个试用版,不给钱就只能用50次,太小气了!!好在头头催得不紧,时间充裕,干脆自己试着做一个,既可长经验值,又能长成就感,不试白不试!以下介绍的便是俺折腾了两天半捣鼓出来的一个只能说是雏形的玩意,区区三十行代码,大侠们不要笑俺哦,这只是写给与俺一样好奇心强但经验值低的弟兄们看的。

  文件上载所需的第一步当然是进入一个有“file”表单元素的页面,具体就不说了,大家都知道。但是若想做一个能够接受该文件并且将其保存到服务器硬盘上的组件,必须知道所提交的原始数据的怎么一个模样才行。做到这一点并不难:

  <%
   Dim FormData,FormSize
   FormSize=Request.TotalBytes
   FormData=Request.BinaryRead(FormSize)
   Response.BinaryWrite FormData
  %>

  因为需要读取的是前一个页面提交来的原始字节数据,因此不能使用Request.Form()方法,必须使用BinaryRead方法,并且一旦使用了这个方法,就不能再在同一个页面中使用Form()方法了,反之亦然。基于同样的道理,向页面输出时也必须使用BinaryWrite方法,不过这并不妨碍你继续使用Response.Write方法。

  在下面的描述中假设浏览者选择上传的文件是一个GIF图片,你会发现这段代码运行的结果并不是在浏览器上显示出这幅图片,而只是输出了一堆基本上是乱七八糟的字符:

-----------------------------7ce20d227c0232
Content-Disposition: form-data; name="file"; filename="C:\mypic.gif"
Content-Type: image/gif

GIF89a  垐??!?倇挌7昳€聉}$挝顿藶排湃缺哪浇爬⒖咯技Φ档北发创熍皗獂勃姰畾棩ゥ挝顿藶排湃缺哪浇爬⒖咯技Φ档北发创熍皗獂勃姰畾棩ゥゥ挗|櫃櫇潒櫃嚈櫃殦x敂儘崓潅倢寍檱Z杹r?杽Z剟剠厁儍t??p{{{zzszzlsss媙arrj僯jrre€ccfff乨Xfffddjj^fffddZ__UZZZYYSWWMRRRRRJ_BBKKK?IIB? ??W::AAA?S;?-----------------------------7ce20d227c0232--


  不奇怪,这就对了!因为原始数据并不仅仅是图片文件本身的数据,它还包含有对该文件在用户硬盘上的路径、类型、提交页面的表单域名等相关信息的描述,以及头尾两段基本相同的标识(即“-----------------------------7ce20d227c0232”),我想这对标识应该是在表单中含有多个元素时起分割作用的。中间的那段数据,即以“GIF89a”开头,直到最后一个“;”,才是我们所想得到的GIF图片文件的数据。若想让浏览器能够显示出这幅图片,当然得先把这些不需要的内容去掉再向页面输出。因此下面该做些什么就很明了了。

  第一步,掐头:
  “头”与图片数据的分界线就是两对回车换行符(在浏览器中是看不到“GIF89a”之前的那个空白行的,得把输出结果粘贴到写字板里去研究,记事本也不行)。

  Dim DataStart,CLStr

  CLStr=ChrB(13) & ChrB(10)

  DataStart=InStrB(FormData,CLStr & CLStr)+4

  其中的4是两对回车换行符的长度,另外要注意这里都是在针对字节数据进行操作,而不是字符,因此不要用错了函数,少敲了个“B”就完全得不到正确结果了。

  第二步,去尾:

  “头”有多大算是搞清了,那尾呢?不急,先获取开头那段标识的具体内容,注意它的结尾处是一对回车换行符:

  Dim DivStr


  DivStr=LeftB(FormData,InStrB(FormData,CLStr)-1)

  因为我们将要使用MidB方法截取图片数据,所以接下来需要搞清楚整段图片数据的字节数,就用前面已定义了的DataSize变量:

  DataSize=InStrB(DataStart+1,FormData,DivStr)-DataStart-2

  为什么要减2呢?因为末尾那段标识之前也有一对回车换行符。至此,图片数据便可以很轻易地得到并在浏览器上输出了:

  FormData=MidB(FormData,DataStart,DataSize)

  Response.BinaryWrite FormData

  不过我想你一定不会满足于到此为止的,因为还没有存盘呢!当然我也不会做到这里便收工,否则是没法向头头交差的。前面所探讨的这些内容都还只局限在纯粹的ASP脚本程序范围内,并没有涉及到组件技术。其实我一开始并没有想向这方面努力,只想靠ASP解决问题,可惜FileSystemObject没告诉我它可以往硬盘上写二进制文件,在这个论坛上问了半天也没人睬我,只好自己动手编组件了。

  不过接下来的过程并不像想象中的那样艰难。

  所要做的这个组件的功能很简单,只提供了一个方法:SaveFile(Pathname),在这个方法内,程序首先获取上传页面所提交的文件的字节数据,就象前文所述的脚本程序一样,然后再将这些数据写到服务器硬盘上由参数Pathname所指定的一个二进制文件内,一切便大功告成了,至于如何使这个组件进一步完善些,呵呵,以后慢慢来吧。

  具体怎么做呢?打开VB,然后请听下回分解。


接着上回,新建一个ActiveX DLLs类型的工程,并将缺省的工程名由“Project1”改为“Songbird”(当然你也有权不这样改,呵呵),将缺省的类名由“Class1”改为“FileUp”,至于为什么要这样改,以后你便知道了。
  要想实现读取上传文件字节数据的功能,势必要涉及到Request对象,可是在VB中该怎么做呢?简单,只需要在工程中加入适当的类型库的参考即可。点击Project菜单选择References,在随之出现的对话框中选中Microsoft Active Server Pages Object项以及Microsoft Transaction Server Type Library项,单击OK,便可以在VB环境中象写ASP代码一样操纵Request、Response等对象了,你会感到非常亲切的。
  以下便是具体的程序代码:

  Public Function SaveFile(Pathname As String) As String
    OnError Goto ErrorCode
    Dim objContext As ObjectContext
    Dim objRequest As Request

    'ObjectContext的使用类似于ASP中的Application和Session对象,
    '可以用关键值对其内部的一些特定的对象实例进行访问,
    '如ObjectContext("Response")

    Set objContext=GetObjectContext()
    Set objRequest=objContext("Request")

    '以下的一段代码与前文的脚本程序类似,
    '只不过对变量的定义要严格些

    Dim FormData() As Byte,CLStr,DivStr
    Dim DataStart As Long,DataSize As Long

    DataSize=objRequest.TotalBytes
    Redim FormData(DataSize-1)
    FormData=objRequest.BinaryRead(DataSize)
    CLStr=ChrB(13) & ChrB(10)
    DataStart=InStrB(FormData,CLStr & CLStr)+4
    DivStr=LeftB(FormData,InStrB(FormData,CLStr)-1)
    DataSize=InStrB(DataStart+1,FormData,DivStr)-DataStart-2
    FormData=MidB(FormData,DataStart,DataSize)

    '创建一个二进制文件并将FormData写入其中
    Open Pathname For Binary As 1
    Put #1,,FormData
    Close #1

    SaveFile="OK!"
    Exit Function
  ErrorCode: SaveFile=Err.Description
  End Function
  
  大功告成!剩下的便是怎样使用这段程序了。
  点击File菜单,选择Make Songbird.dll,系统便会将这段程序编译成DLL文件并自动在本机进行注册。除非你直接在服务器上开发,否则应将此文件拷贝到NT服务器的System32目录下并运行“regsvr32 Songbird.dll”命令进行注册。注册成功之后,在负责接受上传文件的那个ASP文件中这样使用该组件:
  <%
   Dim fu
   Set fu=Server.CreateObject("Songbird.FileUp")
   '用惯了CreateObject("ADODB.Connection"),
   '此时看见了用自己的大名命名的组件,俺的内心立马充满了无限的激动,
   '哈哈哈哈!...@#$%&*,对不起,抒情好象不是俺的强项,呵呵

   '将文件保存到服务器的D盘根目录下
   Response.Write fu.SaveFile("D:\a.gif")
   Set fu=Nothing
  %>
  OK!希望你在浏览器上看到的是“OK!”

  注:
  1、这个组件只实现了最最基本的功能,尚不实用,自己用用、哄哄头头也就算了。写出来的目的只是为了让感兴趣的朋友共享其中一些可资利用的东西。
  2、往NT服务器上传文件时,必须确保浏览者对目标文件夹至少拥有添加和更改的权限,否则会报“File Name or Number Error”。
  3、在书写截取文件数据的语句时注意不要搞错字节数,否则程序运行时并不会报错,但服务器收到的只是一堆无用的字节。
  4、虽然本文是围绕着上传一GIF图片文件展开描述的,但无论上传其它何种类型的文件道理都是一样的,不用改动组件的源程序,只需在使用该组件时为目标文件名指定一正确的扩展名即可。

28,406

社区成员

发帖
与我相关
我的任务
社区描述
ASP即Active Server Pages,是Microsoft公司开发的服务器端脚本环境。
社区管理员
  • ASP
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧