最近上级安排做一个文件夹上传的需求,刚开始研究了Flex,学习利用FileReferance做多选文件上传,结果发现没有选文件夹的功能,又去做了桌面应用程序,发现File对象可以选择文件夹遍历文件逐个上传,当时喜出望外,以为可以实现功能,结果搞没搞懂是否能嵌入HTML,时间不等人,还是放弃。
没办法,根据上级指示,又去啃VB,以前做页面时用过VBS,果断学习之。
         学了几天,搜了百度,实现选择文件夹,遍历文件,生成层级关系的json格式文件属性数据。学习了打包,整合到JSP页面,结合js,在页面展示选择后的文件夹以及所有文件。花了很长时间研究inet控件模拟发送http post请求,百度搜索,不断尝试终于试成功发送请求,在JSP模拟接收请求,利用fileuploadservlet包解析请求,刚开始一直收不到数据,FileItem老是为空,花了很多时间在拼请求数据上面,后面是由于格式问题影响不能收到数据,拼对格式,这个问题解决。
      读取数据又遇到了问题,到目前还没解决,我使用的是读取二进制方式,open #filenum  for binary as #filenum  方式读取,按照文件大小,控制一次读取1M字节数,循环读取,循环发送,后台代码使用随机IO读写文件方式写入。如果是读取文本文件时,使用Get #filenum, ,data  data 为字节数组,然后转换为字符串str=StrConv(data,vbUnicode),传送发送拼接请求信息,后台可以正常保存。但是如果选择的文件是word,pdf,rar压缩包等就出现问题,经过strconv函数转换后的字符传后台,发现字节数比文件大小小了很多,上传后文件老是说文件头损坏之类的提示,没搞清楚怎么转回正常的字节。
尝试了base64转码,生成字符串,后台收到后使用jdk提供的Base64Decoder解码,可以正常上传文件,但是VB进行base64编码很慢,一次读取100K都要等很久,并且页面卡顿,不知哪位大师指点下,这里是否还有更好的方法?但是Java代码解码却很快,不用一秒。
后来直接遍历data字节数组,取出每个字节的数据,形成0~256之间的值,拼成数字字符串,使用逗号分割,传送后台转换为字节数组写入文件,也可行,但偏偏是VB里字节遍历拼字符串很慢:
for i=0  To UBound(data)
    Str  = str  & data(i)&","
next i
这段代码执行很慢,读取100K也慢个半死。目前是尝试了这三种方式,都不尽人意,盼望高手指点。3.问题三,还遇到一个inet控件post请求问题,循环post请求,假如请求10次,中间总有1到2次请求没成功,发送数据断片,inet_stateChanged方法接收请求为icResponseCompleted,但是没有收到后天返回的应答,也就是没有请求成功。
4.问题四,需要展示上传速率,进度度条,需要VB代码调用Js方式,回送数据。VB怎么回调js函数问题(O_O)?
5.问题五,怎么把js函数名称直接赋值给Vb的一个变量?VB就通过这个变量回调这个js函数??

解决方案 »

  1.   

    搜“robocopy”
      

  2.   

    有需要的话我可以给你设计一个本地上传的代码,上传到jsp
      

  3.   

    如果不考虑传输层技术,简单从http协议看,可以给你个http包,只要你模拟这个包连接服务器后发包就完事了。
    如果考虑传输技术,可以选择xmlhttp组件或winsock控件或socket api来打造自己的传输层。
    可以简单说下优略:
    xmlhttp组件      不同的系统,不同的版本和平台有着不同的表现,因为是第三方组件,所以出了基础问题有时候没法自己解决,只能换版本或等补丁,如果在用户机器上,那就去维护吧。可能出现的致命问题就是缓存,如果他认为你的提交地址需要缓存,甚至连网络都不动用直接返回个缓存结果给你,当然有什么改变url的方法来解决这种问题,但并不是什么版本什么系统都一定有效的。winsock控件    不同版本和系统表现也不一样,主要在于稳定性,还有你对winsock控件的熟悉程度,通常情况下是正常的,但到了internet上,有时候你会发现意外还是有的,这时候你就要学会过滤数据和做n的的校验,不然肯定会爆。还有就是你还要考虑http传输协议,如果要完善那需要全部自己弄,什么算法呀、格式呀、协议呀一堆堆。socket api       兼容性最好了,不过工作量要大很多,而且还要清晰的了解该如何使用,除了要了解比较多的使用步骤和模型,还要考虑到VB6的特性,选择好模型做出有一定效率并且稳定的 socket 类并不容易。然后才去做什么http协议。相对来说xmlhttp上传最为简单,但同时可靠性最低。
    winsock控件适中,不过要做很多的校验来过滤internet上的怪东西。
    而socket api 最为复杂,但也是可靠性最高的,不过工作量和技术要求相对要多一些。
    好了,给你个POST包,你就可以自己研究了POST /upfile.php HTTP/1.1
    Host: localhost
    Connection: keep-alive
    Content-Length: 484
    Cache-Control: max-age=0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Origin: http://localhost
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzNMzgpQrsNEFud2y
    Referer: http://localhost/xxx.htm
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.8
    Cookie: PHPSESSID=h69ks340p5q5bdq9m5cefs01r9sc7grl; ------WebKitFormBoundaryzNMzgpQrsNEFud2y
    Content-Disposition: form-data; name="ucode"TUPrKMxV038dWinA
    ------WebKitFormBoundaryzNMzgpQrsNEFud2y
    Content-Disposition: form-data; name="sid"17
    ------WebKitFormBoundaryzNMzgpQrsNEFud2y
    Content-Disposition: form-data; name="item"licence
    ------WebKitFormBoundaryzNMzgpQrsNEFud2y
    Content-Disposition: form-data; name="file"; filename="test.jpg"
    Content-Type: image/jpegMTA=
    ------WebKitFormBoundaryzNMzgpQrsNEFud2y--
    要注意的是
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzNMzgpQrsNEFud2y
    和每段中间的
    ------WebKitFormBoundaryzNMzgpQrsNEFud2y
    是差两个“--”的,千万别搞错