设为首页 收藏本站
查看: 877|回复: 0

[经验分享] 使用Flex实现FTP文件上传功能

[复制链接]

尚未签到

发表于 2016-6-9 08:59:38 | 显示全部楼层 |阅读模式
使用Flex实现FTP文件上传功能
2011年04月12日
  最近需要使用Flex实现Ftp文件上传功能,Google到chuangxin兄弟的blog正好有相应的文章及代码,甚喜,忙收藏并拜读之。
  搞明白原理后,实测时却发现几个问题:
  1、发送FTP命令时无响应。可以正常连接服务器,但发送登录用户名后便失去响应,一直到连接超时。
  解决方法:这问题解决时间最长,Google了一下午才找到解决方法。发送FTP命令时,结束符号应该是\r\n,而不是之前的\r。
  2、上传文件尾部数据丢失,文件上传不全。13.5k的测试文件只能上传12k,文件尾部数据丢失。本问题有规律可循,结合代码排查起来比较容易。
  解决方法:修改sendData函数内条件判断语句,到达文件尾部时先写数据再退出,而不是直接退出。
  3、文件名为中文,则上传后文件名变乱码。
  解决方法:发送FTP命令时使用UTF-8编码。
  为了看着方便,后面直接贴出修改后的代码。以下内容转自chuangxin的blog,文章地址http://blog.csdn.net/chuangxin/archive/2010/10/10/ 5931986.aspx.代码部分有略微修正。
  Flex FTP文件上传原理就是利用Flex Socket组件与FTP服务器进行网络通讯并根据FTP协议进行指令发生、接收,数据的传输和接收。本文指的是Flex web应用的FTP文件上传,具体实现有下述3个工作:
  1)上传文件选择、加载,可以使用Flex的FileRefrence组件;
  2)socket创建、连接、ftp用户登录信息的验证;
  3)文件数据发送;
  先假设要上传的文件名称为:demo.doc, 该上传的文件内容为fileData,下述为FTP文件上传的核心类。 package fileupload { import flash.events.Event; import flash.events.IEventDispatcher; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.net.FileReference; import flash.net.Socket; import flash.utils.ByteArray; import flash.utils.clearInterval; import flash.utils.setInterval; public class FtpFileUpDownload { private var ftpSocket:Socket; private var ftpResponce:String; private var dataSocket:Socket; private var dataResponse:String; private var clientIP:String; private var clientPort:uint; private var canceled:Boolean = false; private var dispatcher:IEventDispatcher; private var fileName:String; private var fileData:ByteArray; private var _isAnonymous:Boolean = false; private var _userName:String; private var _serverIP:String; private var _userPwd:String; private var _userDir:String; private var _serverPort:uint = 21; private var intervalID:int; // public function FtpFileUpDownload(dispatcher:IEventDispatcher) { this.dispatcher = dispatcher; } /** * isAnonymous, FTP 是否允许 匿名访问,默认为false */ public function get isAnonymous():Boolean{ return _isAnonymous; } public function set isAnonymous(value:Boolean):void{ _isAnonymous = value; } public function get userName():String{ return _userName; } public function set userName(value:String):void{ _userName = value; } public function get serverIP():String{ return _serverIP; } public function set serverIP(value:String):void{ _serverIP = value; } public function get userPwd():String{ return _userPwd; } public function set userPwd(value:String):void{ _userPwd = value; } /** * userDir, FTP 用户上传目录 */ public function get userDir():String{ return _userDir; } public function set userDir(value:String):void{ _userDir = value; } public function get serverPort():uint{ return _serverPort; } public function set serverPort(value:uint):void{ _serverPort = value; } /** * upload file, data is null is not allowed. */ public function upload(data:ByteArray, fileName:String):void{ this.fileName = fileName; this.fileData = data; if(data==null){ dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR,"Dat a is null is not allowed!")); return; } if(!check()) return; connect(); } private function check():Boolean{ var blnResult:Boolean = true; if(!isAnonymous){ if(StringUtil.isEmpty(userName) || StringUtil.isEmpty(userPwd)){// dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR, "请输入用户名和口令!")); blnResult = false; } } if(StringUtil.isEmpty(serverIP)){ dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR, "请输入FTP服务器IP地址!")); blnResult = false; } return blnResult; } private function connect():void{ ftpSocket = new Socket(serverIP, serverPort); ftpSocket.addEventListener(ProgressEvent.SOCKET_DA TA, ftpSocketDataHandle); ftpSocket.addEventListener(SecurityErrorEvent.SECU RITY_ERROR,ftpSocketSecurityErrorHandle); ftpSocket.addEventListener(IOErrorEvent.IO_ERROR,f tpIOErrorHandle); } private function ftpIOErrorHandle(evt:IOErrorEvent):void { dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR,evt. text)); } private function ftpSocketSecurityErrorHandle(evt:SecurityErrorEven t):void { dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR,evt. text)); } private function dataSocketSecurityErrorHandle(evt:SecurityErrorEve nt):void { dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR,evt. text)); } //发送ftpsocket ftp 指令 private function sendCommand(arg:String):void { //arg +="\n"; arg +="\r\n"; //只有\n会导致ftp命令无法发送成功,一直等待直至超时 var content:ByteArray = new ByteArray(); content.writeMultiByte(arg,"gb2312"); ftpSocket.writeBytes(content); ftpSocket.flush(); } private function dataIOErrorHandle(evt:IOErrorEvent):void { dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR,evt. text)); } private function ftpSocketDataHandle(evt:ProgressEvent):void{ ftpResponce = ftpSocket.readUTFBytes(ftpSocket.bytesAvailable); var serverResponse:String =ftpResponce.substr(0, 3); if(ftpResponce.indexOf('227')>-1){ //取得使用者的ip位置 var temp:Object = ftpResponce.substring(ftpResponce.indexOf("(")+1 ,ftpResponce.indexOf(")")); var upLoadSocket_temp:Object = temp.split(","); clientIP = upLoadSocket_temp.slice(0,4).join("."); clientPort = parseInt(upLoadSocket_temp[4])*256+ int(upLoadSocket_temp[5]); //创建上传的ftp连接 dataSocket = new Socket(clientIP,clientPort); dataSocket.addEventListener(ProgressEvent.SOCKET_D ATA, receiveData); dataSocket.addEventListener(IOErrorEvent.IO_ERROR, dataIOErrorHandle); dataSocket.addEventListener(SecurityErrorEvent.SEC URITY_ERROR,dataSocketSecurityErrorHandle); //upload file sendCommand("STOR "+this.fileName); } switch(serverResponse){ case "150": //开始文件传输 curPos = 0; intervalID = setInterval(sendData,30); break; case "220": //FTP连接就绪 sendCommand("USER "+this.userName); break; case "331"://用户名正确,请继续输入口令 sendCommand("PASS "+this.userPwd); break; case "230"://登入成功 //指定下载文件的类型,I是二进位文件,A是字元文件 sendCommand("TYPE A");//设定TYPE为ASCII sendCommand("TYPE I");//设定上传的编码为8-bit binary if(!StringUtil.isEmpty(userDir)) //设定FTP 上传目录 sendCommand("CWD "+userDir); sendCommand("PASV");//passive模式 break; case "250" ://资料夹切换成功 break; case "226"://关闭数据连接。请求的文件操作成功(比如,文件传输或文件终止) ftpSocket.close(); dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.COMPLETED) ); break; case "227" : //Entering Passive Mode (h1,h2,h3,h4,p1,p2). break; case "530": //530 Login incorrect dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR,"用户名或者密码有误!")); break; case "421": dispatcher.dispatchEvent(new FileUpDownloadEvent(FileUpDownloadEvent.ERROR,"连接超时!")); break; default: } trace("ftp response: "+ftpResponce); } private var curPos:int = 0; private function sendData():void{ var fileContents:ByteArray =this.fileData; var fileSize:uint = this.fileData.length; var chunk:uint = 1024*2; //var pos:int = 0; if(curPos+chunk>fileSize){ //以下部分修改。这里如果不改会直接退出,导致最后一部分数据丢失 dataSocket.writeBytes(fileContents,curPos,fileSize -curPos); dataSocket.flush(); //以上部分修改。 dataSocket.close(); clearInterval(intervalID); return; } dataSocket.writeBytes(fileContents,curPos,chunk); dataSocket.flush(); curPos+=chunk; } private function receiveData():void{ var responce:String = dataSocket.readUTFBytes(dataSocket.bytesAvailable) ; trace("dataSocket response: "+responce); } } } FTP文件上传事件代码: package whh.flex.controls.fileupload { import flash.events.Event; public class FileUpDownloadEvent extends Event { public static const ERROR:String = "FILE_UPLOAD_ERROR"; public static const COMPLETED:String = "FILE_UPLOAD_COMPLETED"; public static const CANCEL:String = "FILE_UPLOAD_CANCEL"; // private var _message:String; private var _data:Object; // public function FileUpDownloadEvent(type:String, message:String = null) { super(type,true); this._name = name; this._message = message; } // public function get message():String{ return _message; } public function set message(value:String):void{ _message = value; } } } 则Application中要进行FTP文件上传,可简单codeing为(假设FTPFileUpDownload实例为ftpFile):
  ftpFile.upload(fileData, "demo.doc")
  当然为了侦听ftp上传是否出错、完成,需要侦听FileUpDownloadEvent的Error和Complete事件。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-228059-1-1.html 上篇帖子: AIX系统下如何启动和停止ftp服务 下篇帖子: 使用 Iisftp.vbs 创建 FTP 站点
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表