关键词搜索

源码搜索 ×
×

基于Apache FTP点断续传的文件上传和下载

发布2014-04-18浏览2272次

详情内容

参考地址:http://www.myexception.cn/program/630532.html

基于Apache FTP实现文件上传下载工具 ,上传文件时需要考虑以下问题(实例是续传功能):

(1)、 FTP服务器是否存在改目录,如果不存在目录则需要创建目录。

(2)、判断上传文件是否已经存在,如果存在是需要删除后再上传还是续传。

1、上传或下载状态的枚举类:

  1. package com.scengine.wtms.utils.ftp;
  2. public enum UploadStatus
  3. {
  4. File_Exits(0), Create_Directory_Success(1), Create_Directory_Fail(2), Upload_From_Break_Success(3), Upload_From_Break_Faild(4), Download_From_Break_Success(5), Download_From_Break_Faild(6), Upload_New_File_Success(7), Upload_New_File_Failed(8), Delete_Remote_Success(9), Delete_Remote_Faild(10),Remote_Bigger_Local(11),Remote_smaller_locall(12);
  5. private int status;
  6. public int getStatus()
  7. {
  8. return status;
  9. }
  10. public void setStatus(int status)
  11. {
  12. this.status = status;
  13. }
  14. UploadStatus(int status)
  15. {
  16. this.status = status;
  17. }
  18. }

2、工具类代码:

  1. package com.scengine.wtms.utils.ftp;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. import java.io.PrintWriter;
  9. import org.apache.commons.net.PrintCommandListener;
  10. import org.apache.commons.net.ftp.FTP;
  11. import org.apache.commons.net.ftp.FTPClient;
  12. import org.apache.commons.net.ftp.FTPFile;
  13. import org.apache.commons.net.ftp.FTPReply;
  14. public class ContinueFTP
  15. {
  16. private FTPClient ftpClient = new FTPClient();
  17. /**
  18. * 对象构造 设置将过程中使用到的命令输出到控制台
  19. */
  20. public ContinueFTP()
  21. {
  22. this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
  23. }
  24. /**
  25. *
  26. * java编程中用于连接到FTP服务器
  27. *
  28. * @param hostname
  29. * 主机名
  30. *
  31. * @param port
  32. * 端口
  33. *
  34. * @param username
  35. * 用户名
  36. *
  37. * @param password
  38. * 密码
  39. *
  40. * @return 是否连接成功
  41. *
  42. * @throws IOException
  43. */
  44. public boolean connect(String hostname, int port, String username, String password) throws IOException
  45. {
  46. ftpClient.connect(hostname, port);
  47. if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
  48. {
  49. if (ftpClient.login(username, password))
  50. {
  51. return true;
  52. }
  53. }
  54. disconnect();
  55. return false;
  56. }
  57. /**
  58. *
  59. * 从FTP服务器上下载文件
  60. *
  61. * @param remote
  62. * 远程文件路径
  63. *
  64. * @param local
  65. * 本地文件路径
  66. *
  67. * @return 是否成功
  68. *
  69. * @throws IOException
  70. */
  71. @SuppressWarnings("resource")
  72. public boolean download(String remote, String local) throws IOException
  73. {
  74. ftpClient.enterLocalPassiveMode();
  75. ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  76. boolean result;
  77. File f = new File(local);
  78. FTPFile[] files = ftpClient.listFiles(remote);
  79. if (files.length != 1)
  80. {
  81. System.out.println("远程文件不唯一");
  82. return false;
  83. }
  84. long lRemoteSize = files[0].getSize();
  85. if (f.exists())
  86. {
  87. OutputStream out = new FileOutputStream(f, true);
  88. System.out.println("本地文件大小为:" + f.length());
  89. if (f.length() >= lRemoteSize)
  90. {
  91. System.out.println("本地文件大小大于远程文件大小,下载中止");
  92. return false;
  93. }
  94. ftpClient.setRestartOffset(f.length());
  95. result = ftpClient.retrieveFile(remote, out);
  96. out.close();
  97. } else
  98. {
  99. OutputStream out = new FileOutputStream(f);
  100. result = ftpClient.retrieveFile(remote, out);
  101. out.close();
  102. }
  103. return result;
  104. }
  105. /**
  106. *
  107. * 上传文件到FTP服务器,支持断点续传
  108. *
  109. * @param local
  110. * 本地文件名称,绝对路径
  111. *
  112. * @param remote
  113. * 远程文件路径,使用/home/directory1/subdirectory/file.ext
  114. * 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构
  115. *
  116. * @return 上传结果
  117. *
  118. * @throws IOException
  119. */
  120. @SuppressWarnings("resource")
  121. public UploadStatus upload(String local, String remote) throws IOException
  122. {
  123. // 设置PassiveMode传输
  124. ftpClient.enterLocalPassiveMode();
  125. // 设置以二进制流的方式传输
  126. ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  127. UploadStatus result;
  128. // 对远程目录的处理
  129. String remoteFileName = remote;
  130. if (remote.contains("/"))
  131. {
  132. remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);
  133. String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
  134. if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(directory))
  135. {
  136. // 如果远程目录不存在,则递归创建远程服务器目录
  137. int start = 0;
  138. int end = 0;
  139. if (directory.startsWith("/"))
  140. {
  141. start = 1;
  142. } else
  143. {
  144. start = 0;
  145. }
  146. end = directory.indexOf("/", start);
  147. while (true)
  148. {
  149. String subDirectory = remote.substring(start, end);
  150. if (!ftpClient.changeWorkingDirectory(subDirectory))
  151. {
  152. if (ftpClient.makeDirectory(subDirectory))
  153. {
  154. ftpClient.changeWorkingDirectory(subDirectory);
  155. } else
  156. {
  157. System.out.println("创建目录失败");
  158. return UploadStatus.Create_Directory_Fail;
  159. }
  160. }
  161. start = end + 1;
  162. end = directory.indexOf("/", start);
  163. // 检查所有目录是否创建完毕
  164. if (end <= start)
  165. {
  166. break;
  167. }
  168. }
  169. }
  170. }
  171. // 检查远程是否存在文件
  172. FTPFile[] files = ftpClient.listFiles(remoteFileName);
  173. if (files.length == 1)
  174. {
  175. long remoteSize = files[0].getSize();
  176. File f = new File(local);
  177. long localSize = f.length();
  178. if (remoteSize == localSize)
  179. {
  180. return UploadStatus.File_Exits;
  181. } else if (remoteSize > localSize)
  182. {
  183. return UploadStatus.Remote_Bigger_Local;
  184. }
  185. // 尝试移动文件内读取指针,实现断点续传
  186. InputStream is = new FileInputStream(f);
  187. if (is.skip(remoteSize) == remoteSize)
  188. {
  189. ftpClient.setRestartOffset(remoteSize);
  190. if (ftpClient.storeFile(remote, is))
  191. {
  192. return UploadStatus.Upload_From_Break_Success;
  193. }
  194. }
  195. // 如果断点续传没有成功,则删除服务器上文件,重新上传
  196. if (!ftpClient.deleteFile(remoteFileName))
  197. {
  198. return UploadStatus.Delete_Remote_Faild;
  199. }
  200. is = new FileInputStream(f);
  201. if (ftpClient.storeFile(remote, is))
  202. {
  203. result = UploadStatus.Upload_New_File_Success;
  204. } else
  205. {
  206. result = UploadStatus.Upload_New_File_Failed;
  207. }
  208. is.close();
  209. } else
  210. {
  211. InputStream is = new FileInputStream(local);
  212. if (ftpClient.storeFile(remoteFileName, is))
  213. {
  214. result = UploadStatus.Upload_New_File_Success;
  215. } else
  216. {
  217. result = UploadStatus.Upload_New_File_Failed;
  218. }
  219. is.close();
  220. }
  221. return result;
  222. }
  223. /**
  224. *
  225. * 断开与远程服务器的连接
  226. *
  227. * @throws IOException
  228. */
  229. public void disconnect() throws IOException
  230. {
  231. if (ftpClient.isConnected())
  232. {
  233. ftpClient.disconnect();
  234. }
  235. }
  236. public static void main(String[] args)
  237. {
  238. ContinueFTP myFtp = new ContinueFTP();
  239. try
  240. {
  241. myFtp.connect("192.168.1.200", 21, "duser", "HTPDuserXP32");
  242. System.out.println(myFtp.upload("C:\\Users\\Administrator\\Desktop\\swing.drawer.jar", "/jars/swing.drawer.jar"));
  243. myFtp.disconnect();
  244. } catch (IOException e)
  245. {
  246. System.out.println("连接FTP出错:" + e.getMessage());
  247. }
  248. }
  249. }



相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载