FTP客户端(利用sun.net.ftp.FtpClient实现)

  • sun.net.ftp.FtpClient是jdk1.6的org.apache.commons.net.ftp.FTPClient是jdk1.7的使用时要注意

昨天帮同事弄java上传文件到ftp服务器,用的sun.net.ftp.FtpClient,感觉很简单,也很好用,写了个小例子,留作备份。

这个小例子实现了文件(或文件夹)上传,文件下载,取得某目录下文件列表等功能,对于文件夹下载还没有实现,改天有空改完了再贴上来吧。由于通过设定好的用户名、密码登陆到ftp server时,连接到的目录不一定是根目录,有可能是根目录下很深层的一个子目录,比如“usr/why/test/ftp/upload/exercise/20090730”,所以我觉得针对当前连接目录进行操作,要比每次都从根目录开始指定方便。

Java代码  
  1. package com.why.ftp;
  2. import java.io.DataInputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.OutputStream;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.StringTokenizer;
  11. import sun.net.TelnetInputStream;
  12. import sun.net.TelnetOutputStream;
  13. import sun.net.ftp.FtpClient;
  14. /**
  15. * ftp上传,下载
  16. * @author why 2009-07-30
  17. *
  18. */
  19. public class FtpUtil {
  20. private String ip = "";
  21. private String username = "";
  22. private String password = "";
  23. private int port = -1;
  24. private String path = "";
  25. FtpClient ftpClient = null;
  26. OutputStream os = null;
  27. FileInputStream is = null;
  28. public FtpUtil(String serverIP, String username, String password) {
  29. this.ip = serverIP;
  30. this.username = username;
  31. this.password = password;
  32. }
  33. public FtpUtil(String serverIP, int port, String username, String password) {
  34. this.ip = serverIP;
  35. this.username = username;
  36. this.password = password;
  37. this.port = port;
  38. }
  39. /**
  40. * 连接ftp服务器
  41. *
  42. * @throws IOException
  43. */
  44. public boolean connectServer(){
  45. ftpClient = new FtpClient();
  46. try {
  47. if(this.port != -1){
  48. ftpClient.openServer(this.ip,this.port);
  49. }else{
  50. ftpClient.openServer(this.ip);
  51. }
  52. ftpClient.login(this.username, this.password);
  53. if (this.path.length() != 0){
  54. ftpClient.cd(this.path);// path是ftp服务下主目录的子目录
  55. }
  56. ftpClient.binary();// 用2进制上传、下载
  57. System.out.println("已登录到\"" + ftpClient.pwd() + "\"目录");
  58. return true;
  59. }catch (IOException e){
  60. e.printStackTrace();
  61. return false;
  62. }
  63. }
  64. /**
  65. * 断开与ftp服务器连接
  66. *
  67. * @throws IOException
  68. */
  69. public boolean closeServer(){
  70. try{
  71. if (is != null) {
  72. is.close();
  73. }
  74. if (os != null) {
  75. os.close();
  76. }
  77. if (ftpClient != null) {
  78. ftpClient.closeServer();
  79. }
  80. System.out.println("已从服务器断开");
  81. return true;
  82. }catch(IOException e){
  83. e.printStackTrace();
  84. return false;
  85. }
  86. }
  87. /**
  88. * 检查文件夹在当前目录下是否存在
  89. * @param dir
  90. * @return
  91. */
  92. private boolean isDirExist(String dir){
  93. String pwd = "";
  94. try {
  95. pwd = ftpClient.pwd();
  96. ftpClient.cd(dir);
  97. ftpClient.cd(pwd);
  98. }catch(Exception e){
  99. return false;
  100. }
  101. return true;
  102. }
  103. /**
  104. * 在当前目录下创建文件夹
  105. * @param dir
  106. * @return
  107. * @throws Exception
  108. */
  109. private boolean createDir(String dir){
  110. try{
  111. ftpClient.ascii();
  112. StringTokenizer s = new StringTokenizer(dir, "/"); //sign
  113. s.countTokens();
  114. String pathName = ftpClient.pwd();
  115. while(s.hasMoreElements()){
  116. pathName = pathName + "/" + (String) s.nextElement();
  117. try {
  118. ftpClient.sendServer("MKD " + pathName + "\r\n");
  119. } catch (Exception e) {
  120. e = null;
  121. return false;
  122. }
  123. ftpClient.readServerResponse();
  124. }
  125. ftpClient.binary();
  126. return true;
  127. }catch (IOException e1){
  128. e1.printStackTrace();
  129. return false;
  130. }
  131. }
  132. /**
  133. * ftp上传
  134. * 如果服务器段已存在名为filename的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
  135. *
  136. * @param filename 要上传的文件(或文件夹)名
  137. * @return
  138. * @throws Exception
  139. */
  140. public boolean upload(String filename){
  141. String newname = "";
  142. if(filename.indexOf("/") > -1){
  143. newname = filename.substring(filename.lastIndexOf("/") + 1);
  144. }else{
  145. newname = filename;
  146. }
  147. return upload(filename, newname);
  148. }
  149. /**
  150. * ftp上传
  151. * 如果服务器段已存在名为newName的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
  152. *
  153. * @param fileName 要上传的文件(或文件夹)名
  154. * @param newName 服务器段要生成的文件(或文件夹)名
  155. * @return
  156. */
  157. public boolean upload(String fileName, String newName){
  158. try{
  159. String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
  160. File file_in = new File(savefilename);//打开本地待长传的文件
  161. if(!file_in.exists()){
  162. throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
  163. }
  164. if(file_in.isDirectory()){
  165. upload(file_in.getPath(),newName,ftpClient.pwd());
  166. }else{
  167. uploadFile(file_in.getPath(),newName);
  168. }
  169. if(is != null){
  170. is.close();
  171. }
  172. if(os != null){
  173. os.close();
  174. }
  175. return true;
  176. }catch(Exception e){
  177. e.printStackTrace();
  178. System.err.println("Exception e in Ftp upload(): " + e.toString());
  179. return false;
  180. }finally{
  181. try{
  182. if(is != null){
  183. is.close();
  184. }
  185. if(os != null){
  186. os.close();
  187. }
  188. }catch(IOException e){
  189. e.printStackTrace();
  190. }
  191. }
  192. }
  193. /**
  194. * 真正用于上传的方法
  195. * @param fileName
  196. * @param newName
  197. * @param path
  198. * @throws Exception
  199. */
  200. private void upload(String fileName, String newName,String path) throws Exception{
  201. String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
  202. File file_in = new File(savefilename);//打开本地待长传的文件
  203. if(!file_in.exists()){
  204. throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
  205. }
  206. if(file_in.isDirectory()){
  207. if(!isDirExist(newName)){
  208. createDir(newName);
  209. }
  210. ftpClient.cd(newName);
  211. File sourceFile[] = file_in.listFiles();
  212. for(int i = 0; i < sourceFile.length; i++){
  213. if(!sourceFile[i].exists()){
  214. continue;
  215. }
  216. if(sourceFile[i].isDirectory()){
  217. this.upload(sourceFile[i].getPath(),sourceFile[i].getName(),path+"/"+newName);
  218. }else{
  219. this.uploadFile(sourceFile[i].getPath(),sourceFile[i].getName());
  220. }
  221. }
  222. }else{
  223. uploadFile(file_in.getPath(),newName);
  224. }
  225. ftpClient.cd(path);
  226. }
  227. /**
  228. *  upload 上传文件
  229. *
  230. * @param filename 要上传的文件名
  231. * @param newname 上传后的新文件名
  232. * @return -1 文件不存在 >=0 成功上传,返回文件的大小
  233. * @throws Exception
  234. */
  235. public long uploadFile(String filename, String newname) throws Exception{
  236. long result = 0;
  237. TelnetOutputStream os = null;
  238. FileInputStream is = null;
  239. try {
  240. java.io.File file_in = new java.io.File(filename);
  241. if(!file_in.exists())
  242. return -1;
  243. os = ftpClient.put(newname);
  244. result = file_in.length();
  245. is = new FileInputStream(file_in);
  246. byte[] bytes = new byte[1024];
  247. int c;
  248. while((c = is.read(bytes)) != -1){
  249. os.write(bytes, 0, c);
  250. }
  251. }finally{
  252. if(is != null){
  253. is.close();
  254. }
  255. if(os != null){
  256. os.close();
  257. }
  258. }
  259. return result;
  260. }
  261. /**
  262. * 从ftp下载文件到本地
  263. *
  264. * @param filename 服务器上的文件名
  265. * @param newfilename 本地生成的文件名
  266. * @return
  267. * @throws Exception
  268. */
  269. public long downloadFile(String filename, String newfilename){
  270. long result = 0;
  271. TelnetInputStream is = null;
  272. FileOutputStream os = null;
  273. try{
  274. is = ftpClient.get(filename);
  275. java.io.File outfile = new java.io.File(newfilename);
  276. os = new FileOutputStream(outfile);
  277. byte[] bytes = new byte[1024];
  278. int c;
  279. while ((c = is.read(bytes)) != -1) {
  280. os.write(bytes, 0, c);
  281. result = result + c;
  282. }
  283. }catch (IOException e){
  284. e.printStackTrace();
  285. }finally{
  286. try {
  287. if(is != null){
  288. is.close();
  289. }
  290. if(os != null){
  291. os.close();
  292. }
  293. } catch (IOException e) {
  294. e.printStackTrace();
  295. }
  296. }
  297. return result;
  298. }
  299. /**
  300. * 取得相对于当前连接目录的某个目录下所有文件列表
  301. *
  302. * @param path
  303. * @return
  304. */
  305. public List getFileList(String path){
  306. List list = new ArrayList();
  307. DataInputStream dis;
  308. try {
  309. dis = new DataInputStream(ftpClient.nameList(this.path + path));
  310. String filename = "";
  311. while((filename = dis.readLine()) != null){
  312. list.add(filename);
  313. }
  314. } catch (IOException e) {
  315. e.printStackTrace();
  316. }
  317. return list;
  318. }
  319. public static void main(String[] args){
  320. FtpUtil ftp = new FtpUtil("133.224.202.2","tstbill","tstbill");
  321. ftp.connectServer();
  322. boolean result = ftp.upload("C:/test_why", "test_why/test");
  323. System.out.println(result?"上传成功!":"上传失败!");
  324. List list = ftp.getFileList("test_why/test");
  325. for(int i=0;i<list.size();i++){
  326. String name = list.get(i).toString();
  327. System.out.println(name);
  328. }
  329. ftp.closeServer();
  330. /**
  331. FTP远程命令列表
  332. USER    PORT    RETR    ALLO    DELE    SITE    XMKD    CDUP    FEAT
  333. PASS    PASV    STOR    REST    CWD     STAT    RMD     XCUP    OPTS
  334. ACCT    TYPE    APPE    RNFR    XCWD    HELP    XRMD    STOU    AUTH
  335. REIN    STRU    SMNT    RNTO    LIST    NOOP    PWD     SIZE    PBSZ
  336. QUIT    MODE    SYST    ABOR    NLST    MKD     XPWD    MDTM    PROT
  337. 在服务器上执行命令,如果用sendServer来执行远程命令(不能执行本地FTP命令)的话,所有FTP命令都要加上\r\n
  338. ftpclient.sendServer("XMKD /test/bb\r\n"); //执行服务器上的FTP命令
  339. ftpclient.readServerResponse一定要在sendServer后调用
  340. nameList("/test")获取指目录下的文件列表
  341. XMKD建立目录,当目录存在的情况下再次创建目录时报错
  342. XRMD删除目录
  343. DELE删除文件
  344. */
  345. }
  346. }

下面是FtpClient类的一些介绍:

sun.net.ftp.FtpClient.,该类库主要提供了用于建立FTP连接的类。利用这些类的方法,编程人员可以远程登录到FTP服务器,列举该服务器上的目录,设置传输协议,以及传送文件。FtpClient类涵盖了几乎所有FTP的功能,FtpClient的实例变量保存了有关建立"代理"的各种信息。下面给出了这些实例变量:

  public static boolean useFtpProxy
  这个变量用于表明FTP传输过程中是否使用了一个代理,因此,它实际上是一个标记,此标记若为TRUE,表明使用了一个代理主机。

  public static String ftpProxyHost
  此变量只有在变量useFtpProxy为TRUE时才有效,用于保存代理主机名。

  public static int ftpProxyPort
  此变量只有在变量useFtpProxy为TRUE时才有效,用于保存代理主机的端口地址。

  FtpClient有三种不同形式的构造函数,如下所示:

  1、public FtpClient(String hostname,int port)
   此构造函数利用给出的主机名和端口号建立一条FTP连接。

  2、public FtpClient(String hostname)
  此构造函数利用给出的主机名建立一条FTP连接,使用默认端口号。

  3、FtpClient()
  此构造函数将创建一FtpClient类,但不建立FTP连接。这时,FTP连接可以用openServer方法建立。

  一旦建立了类FtpClient,就可以用这个类的方法来打开与FTP服务器的连接。类ftpClient提供了如下两个可用于打开与FTP服务器之间的连接的方法。

  public void openServer(String hostname)
  这个方法用于建立一条与指定主机上的FTP服务器的连接,使用默认端口号。

  public void openServer(String host,int port)
  这个方法用于建立一条与指定主机、指定端口上的FTP服务器的连接。

  打开连接之后,接下来的工作是注册到FTP服务器。这时需要利用下面的方法。

  public void login(String username,String password)
  此方法利用参数username和password登录到FTP服务器。使用过Intemet的用户应该知道,匿名FTP服务器的登录用户名为anonymous,密码一般用自己的电子邮件地址。

  下面是FtpClient类所提供的一些控制命令。

  public void cd(String remoteDirectory):该命令用于把远程系统上的目录切换到参数remoteDirectory所指定的目录。
  public void cdUp():该命令用于把远程系统上的目录切换到上一级目录。
  public String pwd():该命令可显示远程系统上的目录状态。
  public void binary():该命令可把传输格式设置为二进制格式。
  public void ascii():该命令可把传输协议设置为ASCII码格式。
  public void rename(String string,String string1):该命令可对远程系统上的目录或者文件进行重命名操作。

  除了上述方法外,类FtpClient还提供了可用于传递并检索目录清单和文件的若干方法。这些方法返回的是可供读或写的输入、输出流。下面是其中一些主要的方法。

  public TelnetInputStream list()
  返回与远程机器上当前目录相对应的输入流。

  public TelnetInputStream get(String filename)
  获取远程机器上的文件filename,借助TelnetInputStream把该文件传送到本地。

  public TelnetOutputStream put(String filename)
  以写方式打开一输出流,通过这一输出流把文件filename传送到远程计算机。

FTP客户端(利用sun.net.ftp.FtpClient实现)相关推荐

  1. java 中sun.net.ftp_开发FTP不要使用sun.net.ftp.ftpClient

    转自:http://cai21cn.iteye.com/blog/700188 在开发一个web应用过程中,需要开发一个服务使用ftp功能将数据传输一个网外的ftp服务器.最初使用sun.net.ft ...

  2. Linux - Ftp客户端安装、创建Ftp用户和登录

    一.安装客户端 [root@xl ~]# yum install ftp 二.创建用户 # 以root用户登录后,增加名为 xlftp 的用户,并指定 xlftp 用户的主目录为 /home/xlft ...

  3. 建立远程ftp服务器,利用无线路由器建立FTP服务器

    路由器的应用非常广泛,无线路由器技术也更加的完善和稳定,利用无线路由器能构建FTP服务器.下面,我就具体的方法在这里拿出来和大家分享一下,希望对大家有用. 一.FTP FTP(文件传输协议)诞生之后, ...

  4. 使用FTP(IOS FTP客户端开发教程)

    本文翻译自新近Wrox出版社出版的,由Peter van de Put所著的<Professional.iOS.Programming>.该书题材比较新颖,结构合理,是一本不错的IOS开发 ...

  5. ftp服务器软件和ftp客户端软件的使用说明

    1. 提出问题 需要电脑上搭建ftp服务器,电脑是windows系统. 2. 分析问题 需要使用ftp服务端工具,搭建ftp服务器. 3. 解决问题 使用xlightftpserver软件搭建ftp服 ...

  6. 简单vsftpd安装配置和 ftp客户端操作笔记

    #安装vsftpd yum install vsftpd #创建要登录ftp的本地用户 useradd -s /bin/false   用户名         #创建禁止ssh登录的用户 passwd ...

  7. 使用sun.net.ftp.FtpClient进行上传功能开发,在jdk1.7上不适用问题的解决

    使用sun.net.ftp.FtpClient进行上传功能开发,在jdk1.7上不适用问题的解决 参考文章: (1)使用sun.net.ftp.FtpClient进行上传功能开发,在jdk1.7上不适 ...

  8. 利用CUTFTP Tranfer Engine开发.NET FTP客户端

    为了解决大文件上传的问题,我曾经也用过XMLHTTP分块,但是感觉还是不够好. 利用FTP的话就会方便服务器文件的管理. 首先安装一个CUTFTP软件,安装好以后,安装的文件夹中会有一个ftpte.e ...

  9. JDK1.7 sun.net.ftp.FtpClient

    sun.net.ftp.FtpClient 这个类在jdk的帮助文档中没有具体的说明,也就是并没有对外公开.并且这个类是在jdk的 rt.jar中实现的. jdk1.7中其构造函数FtpClient( ...

  10. Apache Ftp客户端工具FtpClient

    引入依赖 <dependency><groupId>commons-net</groupId><artifactId>commons-net</a ...

最新文章

  1. php 解决方案,php优化解决方案
  2. 宝塔linux计划任务ftp,宝塔面板定时备份网站及数据库至FTP存储空间图文教程
  3. 理解Java中的弱引用(Weak Reference)
  4. java-Calendar类
  5. nyoj66分数拆分
  6. Semaphore 源码分析
  7. codeforces 1041a(水题)
  8. P2350-[HAOI2012]外星人【线性筛】
  9. canvas图形编辑器
  10. 多窗口售票:单件模式多线程实现
  11. android检测是否跳出应用程序,android – 检测应用程序何时打开/恢复
  12. 理解 PHP output buffer
  13. DOM之事件高级(附实例、图解)
  14. 如何在服务器上上传手游源码,【仙变3手游】跨服服务端游戏源码+架设教程+双端+后台...
  15. 人体神经系统分类图解,人体神经系统分类图片
  16. Android的一个登陆注册页面
  17. 用户注册的邮箱激活模块的设计与实现
  18. 2017网易校招:Fibonacci数列
  19. php抓取快照,PHP抓屏函数实现屏幕快照代码分享
  20. PostgreSQL的hook机制初步学习

热门文章

  1. .NET Core 分析程序集更优方法,超越ReflectionOnlyLoad
  2. 2020华师大个人考研总结
  3. Unity打包exe生成的文件夹合并成单独的exe
  4. 计算机控制点火系统的三个阶段,汽车发动机电控技期末考解答.doc
  5. MMORPG游戏服务器技术选型参考
  6. Python基础语法学习4
  7. 《编程之道》译者序(转载) (转)
  8. JS设计模式(二)-Revealing Module(揭示模式)
  9. python运行报错怎么看_解决python运行启动报错问题
  10. searchEngin_设置bing国际版为默认引擎