logo资料库

Java实现FTP批量大文件上传下载.doc

第1页 / 共45页
第2页 / 共45页
第3页 / 共45页
第4页 / 共45页
第5页 / 共45页
第6页 / 共45页
第7页 / 共45页
第8页 / 共45页
资料共45页,剩余部分请下载后查看
一、        引子
二、        Java FTP客户端库的选择
三、        基本功能
四、  进度条
五、断点续传
六、FTP端口映射
七、Applet回调服务器
用 Java 实现 FTP 批量大文件上传下载(一) 本文介绍了在 Java 中,如何使用 Java 现有的可用的库来编写 FTP 客户端代 码,并开发成 Applet 控件,做成基于 Web 的批量、大文件的上传下载控件。文 章在比较了一系列 FTP 客户库的基础上,就其中一个比较通用且功能较强的 j-ftp 类库,对一些比较常见的功能如进度条、断点续传、内外网的映射、在 Applet 中回调 JavaScript 函数等问题进行详细的阐述及代码实现,希望通过此 文起到一个抛砖引玉的作用。 一、 引子 笔者在实施一个项目过程中出现了一种基于 Web 的文件上传下载需求。在全 省(或全国)各地的用户,需要将一些文件上传至某中心的文件服务器上。这些 文件是用于一些大型的工程建设,可能涉及到上千万甚至上亿的建设工程。文件 具有三个鲜明的特征:一是文件大,可能达到 50M;二是文件数量多,有可能 15 个左右;三是数据安全性方面要求数字签名及数据加密。 首先考虑到是基于 HTTP 的传输方式。但笔者通过比较很快发现满足上面的 需求: 1:用 HTTP 协议上传,似乎更适合 web 编程的方便性;上传小于 1M 文件 速度要比用 FTP 协议上传文件略快。但对于批量及大文件的传输可能无能为力。 当然,它也有它的优势,如不像 FTP 那样,必须在服务器端启动一个 FTP 服务。 2:用 FTP 协议上传文件大于 1M 的文件速度比 HTTP 快。文件越大,上传 的速度就比 HTTP 上传的速度快数倍。而且用 java 编写程序;FTP 比 HTTP 方便。 笔者曾经使用 VB 也写过 ActiveX 控件来进行批量文件的上传下载,其功能 也很强大。只是由于没有对 CAB 文件或 OCX 进行专门的数字签名,因此需要进 行客户端烦琐的设置,如设置安全站点、降低客户端的安全级别等等,因而放弃 了些方案。
同时考虑到在需在客户端对文件进行数字签名及数据加密,决定采用 Applet 的方式实现。。文件上传之前,在客户端可以获取本地 USBKEY 密钥信息,完成 对上传文件的加密和签名处理。虽然采用 Applet 要求在客户端安装 JRE 运行时 环境,给客户端的管理及使用带来一度的不方便性,但是相对起如此大量的文件 及文件的安全性,这也许已经算是比较小的代价了。 总结一下运行的环境为: FTP 服务器端:Serv-U,专业的 FTP 服务器端程序,网上有现成的软件下载, 当然读者也可能自己写一个服务器端的 FTP 文件接收程序来进行解释。如果没有 特殊要求或功能的话,Serv-U 应该可以满足我们一般上传下载的需求了; 客户端:Java applet,当年让 Java 大火了一把的号称与微软的 ActiveX 相 提并论的技术当然,现在 Java 出了 JavaFX,是不是 Applet 的替代品呢? 应用环境:Internet 网,最终目的。 二、 Java FTP 客户端库的选择 让我们设想这样一个情形--我们想写一个纯 Java 的从一个远程计算机上 运行的 FTP 服务器上传下载文件的应用程序;我们还希望能够得到那些供下载的 远程文件的基本文件信息,如文件名、数据或者文件大小等。 尽管从头开始写一个 FTP 协议处理程序是可能的,并且也许很有趣,但这项 工作也是困难、漫长并且存在着潜在的危险。因为我们不愿意亲自花时间、精力、 或者金钱去写这样的一个处理程序,所以我们转而采用那些已经存在的可重用的 组件。并且很多的库存在于网上。 找一个优秀的适合我们需要的 Java FTP 客户端库并不像看起来那么简单。 相反这是一项非常痛苦复杂的工作。首先找到一个 FTP 客户端库需要一些时间, 其次,在我们找到所有的存在的库后,我们该选哪一个呢?每个库都适合不同的 需求。这些库在性能上是不等价的,并且它们的设计上有着根本上的差别。每个
类库都各具特点并使用不同的术语来描述它们。因而,评价和比较 FTP 客户端库 是一件困难的事情。 使用可重用组件是一种值得提倡的方法,但是在这种情况下,刚开始往往是 令人气馁的。后来或许有点惭愧:在选择了一个好的 FTP 库后,其后的工作就非 常简单了,按简单的规则来就行了。目前,已经有很多公开免费的 ftp 客户端类 库,如 simpleftp、J-ftp 等,还有很多其他的 ftpclient。如下表所示,表中未能 全部列出,如读者有更好的客户端 FTP 类库,请进行进一步的补充。 FTP 客户端类库名 J-ftp simpleftp ftpclient FTPProtocol FtpConnection FTPClient FTPClient FtpClient FTP Ftp FTPClient 备注 J-ftp HTTP://www.jibble.org/files/simpleftp.jar com.enterprisedt.net.ftp.FTPClient com.ibm.network.ftp.protocol.FTPProtocol net.sf.jftp.net.FtpConnection org.apache.commons.net.ftp.FTPClient jshop.jnet.FTPClient sun.net.ftp.FtpClient com.cqs.ftp.FTP cz.dhl.ftp.Ftp org.globus.io.ftp.FTPClient 在本文中,笔者采用是 J-ftp。这个是个开源的且功能十分强大的客户端 FTP 类库。笔者很喜欢,同时也向各位读者推荐一下。算了免费为它做一个广告。 三、 基本功能 1、 登陆 采用 FTP 进行文件传输,其实本质上还是采用 Java.net.socket 进行通信。 以下代码只是类 net.sf.jftp.net.FtpConnection 其中一个 login 方法。当然在 下面的代码,为了节省版面,以及将一些原理阐述清楚,笔者将一些没必要的代 码去掉了,如日志等代码。完整的代码请参考 J-ftp 的源代码或是笔者所以的示 例源代码,后面的代码示例也同理:
public int login(String username, String password) { this.username = username; this.password = password; int status = LOGIN_OK; jcon = new JConnection(host, port); if(jcon.isThere()) { in = jcon.getReader(); if(getLine(POSITIVE) == null)//FTP220_SERVICE_READY) == null) { ok = false; status = OFFLINE; } if(!getLine(loginAck).startsWith(POSITIVE))//FTP230_LOGGED_IN)) { if(success(POSITIVE))//FTP230_LOGGED_IN)) { } else { ok = false; status = WRONG_LOGIN_DATA; } }
} else { if(msg) { Log.debug("FTP not available!"); ok = false; status = GENERIC_FAILED; } } if(ok) { connected = true; system(); binary(); String[] advSettings = new String[6]; if(getOsType().indexOf("OS/2") >= 0) { LIST_DEFAULT = "LIST"; } if(LIST.equals("default")) { //just get the first item (somehow it knows first is the //FTP list command) advSettings = LoadSet.loadSet(Settings.adv_settings);
//*** IF FILE NOT FOUND, CREATE IT AND SET IT TO LIST_DEFAULT if(advSettings == null) { LIST = LIST_DEFAULT; SaveSet s = new SaveSet(Settings.adv_settings, LIST); } else { LIST = advSettings[0]; if(LIST == null) { LIST = LIST_DEFAULT; } } } if(getOsType().indexOf("MVS") >= 0) { LIST = "LIST"; } //*** fireDirectoryUpdate(this); fireConnectionInitialized(this); } else { fireConnectionFailed(this, new Integer(status).toString());
} return status; } 此登陆方法中,有一个 JConnection 类,此类负责建立 socket 套接字 ,同时,此类是一 种单独的线程,这样的好处是为了配合界面的变化,而将网络的套接字连接等工作做为单独的线 程来处理,有利于界面的友好性。下面是 net.sf.jftp.net.JConnection 类的 run 方法,当然, 此线程的启动是在 JConnection 类的构造方法中启动的。 public void run() { try { s = new Socket(host, port); localPort = s.getLocalPort(); //if(time > 0) s.setSoTimeout(time); out = new PrintStream(new BufferedOutputStream(s.getOutputStream (), in = new BufferedReader(new InputStreamReader(s.getInputStream()), Settings.bufferSize)); Settings.bufferSize); isOk = true; // } } catch(Exception ex) { ex.printStackTrace(); Log.out("WARNING: connection closed due to exception (" + host +
":" + port + ")"); isOk = false; try { if((s != null) && !s.isClosed()) { s.close(); } if(out != null) { out.close(); } if(in != null) { in.close(); } } catch(Exception ex2) { ex2.printStackTrace(); Log.out("WARNING: got more errors trying to close socket and strea ms"); } } established = true;
分享到:
收藏