关键词搜索

源码搜索 ×
×

基于Apache FTP实现的文件上传下载工具

发布2014-04-18浏览6278次

详情内容

基于Apache FTP实现的文件上传下载工具 ,上传文件时需要考虑以下问题:

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

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

以下示例代码(注:未实现续传功能)。

  1. package com.scengine.wtms.utils.ftp;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;
  9. import java.io.PrintWriter;
  10. import java.net.SocketException;
  11. import java.net.URLEncoder;
  12. import javax.servlet.http.HttpServletResponse;
  13. import org.apache.commons.net.PrintCommandListener;
  14. import org.apache.commons.net.ftp.FTP;
  15. import org.apache.commons.net.ftp.FTPClient;
  16. import org.apache.commons.net.ftp.FTPClientConfig;
  17. import org.apache.commons.net.ftp.FTPFile;
  18. import org.apache.commons.net.ftp.FTPReply;
  19. import com.scengine.wtms.utils.Log;
  20. public class OLDFashionedFTP
  21. {
  22. private FTPClient ftp;
  23. /**
  24. * 对象构造 设置将过程中使用到的命令输出到控制台
  25. */
  26. public OLDFashionedFTP()
  27. {
  28. ftp = new FTPClient();
  29. this.ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
  30. }
  31. /**
  32. * 用户FTP账号登录
  33. *
  34. * @param url
  35. * FTP地址
  36. * @param port
  37. * FTP端口
  38. * @param username
  39. * 用户名
  40. * @param password
  41. * 密 码
  42. * @return true/false 成功/失败
  43. * @throws SocketException
  44. * @throws IOException
  45. */
  46. private boolean login(String url, int port, String username, String password) throws SocketException, IOException
  47. {
  48. int reply;
  49. // 1. 连接FTP服务器
  50. // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
  51. ftp.connect(url, port);
  52. // 2. 设置编码
  53. // 下面三行代码必须要,而且不能改变编码格式,否则不能正确下载中文文件
  54. ftp.setControlEncoding("UTF-8");
  55. FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
  56. conf.setServerLanguageCode("zh");
  57. // 3. 登录ftp
  58. ftp.login(username, password);
  59. // 看返回的值是不是230,如果是,表示登陆成功
  60. reply = ftp.getReplyCode();
  61. // 以2开头的返回值就会为真
  62. if (!FTPReply.isPositiveCompletion(reply))
  63. {
  64. ftp.disconnect();
  65. Log.getLogger(this.getClass()).info(">>>>>>>>>>>>>>>>连接服务器失败!");
  66. return false;
  67. }
  68. Log.getLogger(this.getClass()).info(">>>>>>>>>>>>>>>>>登陆服务器成功!");
  69. return true;
  70. }
  71. /**
  72. * 释放FTP
  73. */
  74. public void disconnect()
  75. {
  76. if (ftp.isAvailable())
  77. {
  78. try
  79. {
  80. ftp.logout(); // 退出FTP
  81. } catch (IOException e)
  82. {
  83. Log.getLogger(this.getClass()).error("FTP登录退出异常:" + e.getMessage());
  84. }
  85. }
  86. if (ftp.isConnected())
  87. {
  88. try
  89. {
  90. // 断开连接
  91. ftp.disconnect();
  92. } catch (IOException e)
  93. {
  94. Log.getLogger(this.getClass()).error("FTP断开连接异常:" + e.getMessage());
  95. }
  96. }
  97. }
  98. /**
  99. * FTP文件上传
  100. *
  101. * @param url
  102. * FTP地址
  103. * @param port
  104. * FTP端口
  105. * @param username
  106. * FTP用户名
  107. * @param password
  108. * FTP密码
  109. * @param localAdr
  110. * 上传文件名
  111. * @param remoteAdr
  112. * 指定的FTP目录
  113. * @return
  114. * @throws IOException
  115. */
  116. public boolean uploadFile(String url, int port, String username, String password, String localAdr, String remoteAdr) throws IOException
  117. {
  118. // 初始表示上传失败
  119. boolean success = false;
  120. /******验证用户登录信息*****/
  121. try
  122. {
  123. success = login(url, port, username, password);
  124. Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));
  125. if (!success)
  126. {
  127. return success;
  128. }
  129. } catch (IOException e)
  130. {
  131. Log.getLogger(this.getClass()).error("上传文件异常:" + e.getMessage());
  132. return success;
  133. }
  134. // 设置PassiveMode传输
  135. ftp.enterLocalPassiveMode();
  136. // 设置FTP文件类型为二进制,如果缺省该句 传输txt正常 但图片和其他格式的文件传输出现乱码
  137. ftp.setFileType(FTP.BINARY_FILE_TYPE);
  138. /*****对远程目录的处理******/
  139. String remoteFileName = remoteAdr;
  140. if (remoteAdr.contains("/"))
  141. {
  142. remoteFileName = remoteAdr.substring(remoteAdr.lastIndexOf("/") + 1);
  143. String directory = remoteAdr.substring(0, remoteAdr.lastIndexOf("/") + 1);
  144. if (!directory.equalsIgnoreCase("/") && !ftp.changeWorkingDirectory(directory))
  145. {
  146. // 如果远程目录不存在,则递归创建远程服务器目录
  147. int start = 0, end = 0;
  148. if (directory.startsWith("/"))
  149. {
  150. start = 1;
  151. } else
  152. {
  153. start = 0;
  154. }
  155. end = directory.indexOf("/", start);
  156. while (true)
  157. {
  158. String subDirectory = remoteAdr.substring(start, end);
  159. if (!ftp.changeWorkingDirectory(subDirectory))
  160. {
  161. if (ftp.makeDirectory(subDirectory))
  162. {
  163. ftp.changeWorkingDirectory(subDirectory);
  164. } else
  165. {
  166. Log.getLogger(this.getClass()).info("创建目录失败");
  167. return false;
  168. }
  169. }
  170. start = end + 1;
  171. end = directory.indexOf("/", start);
  172. // 检查所有目录是否创建完毕
  173. if (end <= start)
  174. {
  175. break;
  176. }
  177. }
  178. }
  179. }
  180. /*****执行文件上传******/
  181. InputStream input = null;
  182. try
  183. {
  184. File f = new File(localAdr);
  185. // 得到目录的相应文件列表
  186. FTPFile[] fs = ftp.listFiles(remoteFileName);
  187. Log.getLogger(this.getClass()).info("上传文件个数:" + fs.length + " ,文件名称:" + localAdr);
  188. input = new FileInputStream(f);
  189. // 保存文件remoteFileName
  190. success = ftp.storeFile(remoteFileName, input);
  191. } catch (IOException e)
  192. {
  193. if (input != null) input.close();
  194. Log.getLogger(this.getClass()).info("上传文件失败:" + e.getMessage());
  195. } finally
  196. {
  197. if (input != null) input.close();
  198. this.disconnect();
  199. Log.getLogger(this.getClass()).info("保存标识>>>" + success + "文件名称:" + localAdr + (success ? "上传成功!" : "上传失败!"));
  200. }
  201. return success;
  202. }
  203. /**
  204. * 删除FTP文件和目录
  205. *
  206. * @param url
  207. * FTP地址
  208. * @param port
  209. * FTP端口
  210. * @param username
  211. * 用户名
  212. * @param password
  213. * 密 码
  214. * @param remoteAdr
  215. * 文件路径
  216. * @param localAdr
  217. * 文件名称
  218. * @return true/false 成功/失败
  219. */
  220. public boolean deleteDirectory(String url, int port, String username, String password, String remoteAdr)
  221. {
  222. boolean success = false;
  223. try
  224. {
  225. success = login(url, port, username, password);
  226. Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));
  227. if (!success)
  228. {
  229. return success;
  230. }
  231. //String remoteAdr_ = new String(remoteAdr.getBytes("UTF-8"), "ISO-8859-1");
  232. // 转到指定上传目录
  233. ftp.changeWorkingDirectory(remoteAdr);
  234. FTPFile[] fs = ftp.listFiles(); // 得到目录的相应文件列表
  235. if(fs.length>0)
  236. {
  237. success = ftp.removeDirectory(remoteAdr);
  238. }
  239. } catch (IOException e)
  240. {
  241. Log.getLogger(this.getClass()).error(e.getMessage());
  242. } finally
  243. {
  244. this.disconnect();
  245. }
  246. return success;
  247. }
  248. /**
  249. * 删除FTP文件
  250. *
  251. * @param url
  252. * FTP地址
  253. * @param port
  254. * FTP端口
  255. * @param username
  256. * 用户名
  257. * @param password
  258. * 密 码
  259. * @param remoteAdr
  260. * 文件路径
  261. * @return true/false 成功/失败
  262. */
  263. public boolean deleteFile(String url, int port, String username, String password, String remoteAdr)
  264. {
  265. boolean success = false;
  266. try
  267. {
  268. success = login(url, port, username, password);
  269. Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));
  270. if (!success)
  271. {
  272. return success;
  273. }
  274. //String remoteAdr_ = new String(remoteAdr.getBytes("UTF-8"), "ISO-8859-1");
  275. // 得到目录的相应文件列表
  276. FTPFile[] fs = ftp.listFiles(remoteAdr);;
  277. if(fs.length>0)
  278. {
  279. // remoteAdr_->remoteAdr
  280. success =ftp.deleteFile(remoteAdr);
  281. }
  282. } catch (IOException e)
  283. {
  284. Log.getLogger(this.getClass()).error(e.getMessage());
  285. } finally
  286. {
  287. this.disconnect();
  288. }
  289. return success;
  290. }
  291. /**
  292. * 下载FTP文件
  293. *
  294. * @param url
  295. * FPT地址
  296. * @param port
  297. * FTP端口
  298. * @param username
  299. * 用户名
  300. * @param password
  301. * 密 码
  302. * @param remoteremoteAdr
  303. * 远程路径
  304. * @param localAdr
  305. * 文件名称
  306. * @param outputStream文件输出流
  307. * @param response
  308. * Http响应
  309. * @return true/false 成功/失败
  310. */
  311. public boolean downFile(String url, int port, String username, String password, String remoteremoteAdr, String localAdr, HttpServletResponse response)
  312. {
  313. boolean success = false;
  314. try
  315. {
  316. success = login(url, port, username, password);
  317. Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));
  318. if (!success)
  319. {
  320. return success;
  321. }
  322. // 转移到FTP服务器目录
  323. ftp.changeWorkingDirectory(remoteremoteAdr);
  324. // 得到目录的相应文件列表
  325. FTPFile[] fs = ftp.listFiles();
  326. for (FTPFile ftpFile : fs)
  327. {
  328. if (ftpFile.getName().equals(localAdr))
  329. {
  330. // 这个就就是弹出下载对话框的关键代码
  331. response.setHeader("Content-disposition", "attachment;localAdr=" + URLEncoder.encode(localAdr, "UTF-8"));
  332. // 将文件保存到输出流outputStream中
  333. File f=new File(localAdr);
  334. OutputStream os=new FileOutputStream(f);
  335. ftp.retrieveFile(new String(ftpFile.getName().getBytes("UTF-8"), "ISO-8859-1"), os);
  336. os.flush();
  337. os.close();
  338. }
  339. }
  340. success = true;
  341. } catch (IOException e)
  342. {
  343. e.printStackTrace();
  344. } finally
  345. {
  346. this.disconnect();
  347. }
  348. return success;
  349. }
  350. /**
  351. * 读取FTP文件内容
  352. *
  353. * @param url
  354. * FPT地址
  355. * @param port
  356. * FTP端口
  357. * @param username
  358. * 用户名
  359. * @param password
  360. * 密 码
  361. * @param remoteremoteAdr
  362. * 远程路径
  363. * @param localAdr
  364. * 文件名称
  365. * @return String 文件内容
  366. */
  367. public String readFileContent(String url, int port, String username, String password, String remoteremoteAdr, String localAdr)
  368. {
  369. String content = null;
  370. try
  371. {
  372. boolean success = login(url, port, username, password);
  373. Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));
  374. if (success)
  375. {
  376. // 转移到FTP服务器目录
  377. ftp.changeWorkingDirectory(remoteremoteAdr);
  378. // 得到目录的相应文件列表
  379. FTPFile[] fs = ftp.listFiles();
  380. for (FTPFile ftpFile : fs)
  381. {
  382. if (ftpFile.getName().equals(localAdr))
  383. {
  384. // 这个就就是弹出下载对话框的关键代码
  385. // 将文件保存到输出流outputStream中
  386. File f=new File(localAdr);
  387. ftp.retrieveFile(new String(ftpFile.getName().getBytes("UTF-8"), "ISO-8859-1"), new FileOutputStream(f));
  388. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  389. ftp.retrieveFile(ftpFile.getName(), bos);
  390. bos.flush();
  391. bos.close();
  392. content = new String(bos.toByteArray(), "UTF-8");
  393. }
  394. }
  395. }
  396. } catch (IOException e)
  397. {
  398. Log.getLogger(FTPUtils.class).error(e.getMessage());
  399. } finally
  400. {
  401. this.disconnect();
  402. }
  403. return content;
  404. }
  405. /**
  406. * 判断是否重名的方法
  407. *
  408. * @param localAdr
  409. * 文件名称
  410. * @param fs
  411. * 文件列表数组
  412. * @return
  413. */
  414. public static boolean isDirExist(String localAdr, FTPFile[] fs)
  415. {
  416. for (FTPFile ftpFile : fs)
  417. {
  418. if (ftpFile.getName().equals(localAdr))
  419. {
  420. return true;
  421. }
  422. }
  423. return false;
  424. }
  425. /**
  426. * 根据重名判断的结果 生成新的文件的名称 更改的重名为 原有名字+[n], n表示数字
  427. *
  428. * @param localAdr
  429. * 文件名称
  430. * @param fs
  431. * FTP文件列表
  432. * @return
  433. */
  434. public static String rename(String localAdr, FTPFile[] fs)
  435. {
  436. int n = 0;
  437. // 创建一个可变的字符串对象 即StringBuffer对象,把localAdr值付给该对象
  438. StringBuffer localAdr_ = new StringBuffer("");
  439. localAdr_ = localAdr_.append(localAdr);
  440. // 重名时改名,遍历存在同名的文件
  441. while (isDirExist(localAdr_.toString(), fs))
  442. {
  443. n++;
  444. String a = "[" + n + "]";
  445. // 最后一出现小数点的位置
  446. int b = localAdr_.lastIndexOf(".");
  447. // 最后一次"["出现的位置
  448. int c = localAdr_.lastIndexOf("[");
  449. if (c < 0)
  450. {
  451. c = b;
  452. }
  453. // 文件的名字
  454. StringBuffer name = new StringBuffer(localAdr_.substring(0, c));
  455. // 后缀的名称
  456. StringBuffer suffix = new StringBuffer(localAdr_.substring(b + 1));
  457. localAdr_ = name.append(a).append(".").append(suffix);
  458. }
  459. return localAdr_.toString();
  460. }
  461. public static void main(String[] args)
  462. {
  463. OLDFashionedFTP ftp = new OLDFashionedFTP();
  464. try
  465. {
  466. ftp.uploadFile("192.168.1.200", 21, "duser", "HTPDuserXP32", "C:\\Users\\Administrator\\Desktop\\backgroud_change.html", "/htmls/backgroud_change.html");
  467. } catch (IOException e)
  468. {
  469. Log.getLogger(OLDFashionedFTP.class).error(e.getMessage());
  470. }
  471. }
  472. }

相关技术文章

最新源码

下载排行榜

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

提示信息

×

选择支付方式

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