`
ekj676mq
  • 浏览: 16427 次
社区版块
存档分类
最新评论

使用Flex实现FTP文件上传功能

 
阅读更多

使用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事件。
分享到:
评论

相关推荐

    Flex实现Ftp上传

    Flex实现Ftp上传功能模块的源码(web应用),实现向FTP上传文件,无需后台语言支持

    flex web ftp上传. 点对点方式 . 支持多文件上传 现打包发布

    NULL 博文链接:https://xieronghua246.iteye.com/blog/907395

    Flex上传文件与下载

    Flex和Servlet结合使用,文件上传、下载

    flex中的文件上传(简单例子)

    // 定义文件的上传路径 private String uploadPath = "G://upload/"; // 限制文件的上传大小 private int maxPostSize = 100 * 1024 * 1024; public FileUploadServlet() { super(); } public void ...

    tt.rar_FLEX FTP_flex

    flex选择文件,包括上传 ,显示,ftp

    Flex教程 ppt格式 简单实用

    数据管理.ppt第21章 XML的处理.ppt第22章 Flex应用程序开发.ppt第23章 Flex应用程序部署.ppt第24章 文件的上传下载.ppt第25章 Mp3播放器.ppt第26章 用户登录.ppt第27章 电子相册.ppt第28章 浏览FTP.ppt第29章 FLV...

    Flex学习大礼包(flex基础教程、flex和java整合)--下载不扣分,童叟无欺

    第24章 文件的上传下载.ppt 第25章 Mp3播放器.ppt 第26章 用户登录.ppt 第27章 电子相册.ppt 第28章 浏览FTP.ppt 第29章 FLV播放器.ppt 第30章 留言板.ppt 第31章 在线书店系统.ppt ├─Flex与JAVA │ ...

    Flex教程.rar

    第01章 Flex简介.ppt ...第24章 文件的上传下载.ppt 第25章 Mp3播放器.ppt 第26章 用户登录.ppt 第27章 电子相册.ppt 第28章 浏览FTP.ppt 第29章 FLV播放器.ppt 第30章 留言板.ppt 第31章 在线书店系统.ppt

    flex完全自学手册 电子教案(PPT)

    2008-07-10 10:54 169472 65848 第24章 文件的上传下载.ppt 2008-07-10 10:57 137728 86032 第25章 Mp3播放器.ppt 2008-07-10 11:00 116736 66591 第26章 用户登录.ppt 2008-07-10 11:02 285184 245454 第27章 电子...

    asp.net知识库

    使用.ashx文件处理IHttpHandler实现发送文本及二进制数据的方法 制作一个简单的多页Tab功能 一完美的关于请求的目录不存在而需要url重写的解决方案! 在C#中实现MSN消息框的功能 XmlHttp实现无刷新三联动ListBox 鼠标...

    speedcommander13含注册码.rar

    SpeedCommander 是一个非常容易使用的文件管理工具!内置两个操作窗口,可以非常容易的对文件进行排序,删除,复制,移动等操作!内置对Zip,CAB等10种压缩格式的完全支持! 支持对压缩文件直接进行搜索,内置的显示工具支持...

    speed commander 14 含注册码

    SpeedCommander 是一个非常容易使用的文件管理工具!内置两个操作窗口,可以非常容易的对文件进行排序,删除,复制,移动等操作!内置对Zip,CAB等10种压缩格式的完全支持! 支持对压缩文件直接进行搜索,内置的显示工具支持...

    中诺企业网站系统 2.0

    1、使用ftp软件上传Upload文件内的所有内容到网站空间 2、将空间的.net版本切换到.net3.5 3、设置空间目录读写权限为:读取与执行、写入,并给予NETWORK SERVICE用户权限 4、修改默认首页设置为:index.htm ...

Global site tag (gtag.js) - Google Analytics