强烈推荐一个纯java的FTP Client库:ftp4j

ftp4j是个很年轻的开源项目,但是试用后发现很好很强大,如果你找一个纯java的FTP库,要支持socks4,socks4a,socks5,http代理,就是他了!
比apache的FTPClient(不支持代理)、半商业的edtFTPj(PRO支持代理,但是要$,而且是系统变量级的代理,不能单个指定)等好用多了,而且是LGPL协议,源码质量很高。(不过如果你需要FTPS及SFTP,那ftp4j不支持)
jar包只有50多k,地址在这里:ftp4j
使用代理的代码:

  1. import java.util.ArrayList;
  2. importit.sauronsoftware.ftp4j.FTPClient;
  3. importit.sauronsoftware.ftp4j.FTPFile;
  4. importit.sauronsoftware.ftp4j.connectors.SOCKS4Connector;
  5. ......
  6. //ftp4j使用socks4代理连接FTP示例,by http://bianbian.org
  7. FTPClientftp = new FTPClient();
  8. SOCKS4Connectorsocks4 = new SOCKS4Connector("127.0.0.1", 1080);
  9. ftp.setConnector(socks4);
  10. ftp.connect("an.ip.or.host", 21);
  11. ftp.login("anonymous", "[email protected]");
  12. ftp.setCharset("gbk");
  13. //list files
  14. FTPFile[]list = ftp.list();
  15. for(FTPFilefile : list) {
  16. System.out.println(file);
  17. }
  18. ftp.disconnect(true);

在解析部分FTP站点的目录list的时候遇到了FTPListParseException(也怪FTP协议没有对LIST格式作出标准)。查看源码发现,主要是两个问题:
1)文件权限不只rwx这三个,附加了s、t(详见http://en.wikipedia.org/wiki/File_system_permissions
2)部分ftpd似乎直接调用的“ls -l”输出目录,第一行是“total xxx”
给作者写信了,说不定下个版本就有Sepcial Thanks to bianbian 了。嘿嘿嘿嘿。。。
修正后的代码(省略后面没有变化的部分):

  1. public class UnixListParser implements FTPListParser {
  2. // bianbian.org: Pattern有问题,修正
  3. privatestatic final Pattern PATTERN = Pattern
  4. .compile("^([dlcbsp//-])[r//-][w//-][xsS//-][r//-][w//-][xsS//-][r//-][w//-][xtT//-]//s+"
  5. + "(?://d+//s+)?//S+//s*//S+//s+(//d+)//s+(?:(//w{3})//s+(//d{1,2}))//s+"
  6. + "(?:(//d{4})|(?:(//d{1,2}):(//d{1,2})))//s+"
  7. + "([^/////*?/"<>|]+)(?: -> ([^////*?/"<>|]+))?$");
  8. privatestatic final DateFormat DATE_FORMAT = new SimpleDateFormat(
  9. "MMM dd yyyy HH:mm", Locale.US);
  10. publicFTPFile[] parse(String[] lines) throws FTPListParseException {
  11. intcurrentYear = new GregorianCalendar().get(Calendar.YEAR);
  12. inti, jump = 0, size = lines.length;
  13. //bianbian.org: glftpd 的第一行和 ls -l 一样,会丢个"total N"过来,先去掉
  14. if(size > 0 && lines[0].startsWith("total")) {
  15. size--;
  16. jump = 1;
  17. }
  18. FTPFile[]ret = new FTPFile[size];
  19. for(i = 0; i < size; i++) {
  20. Matcherm = PATTERN.matcher(lines[i + jump]);
  21. if(m.matches()) {
  22. ret[i] = newFTPFile();
  23. // Retrieve the data.
  24. chartypeChar = m.group(1).charAt(0);
  25. StringsizeString = m.group(2);
  26. StringmonthString = m.group(3);
  27. StringdayString = m.group(4);
  28. StringyearString = m.group(5);
  29. StringhourString = m.group(6);
  30. StringminuteString = m.group(7);
  31. StringnameString = m.group(8);
  32. StringlinkedString = m.group(9);
  33. // Parse the data.
  34. if("-cbsp".indexOf(typeChar) > -1) {
  35. ret[i].setType(FTPFile.TYPE_FILE);
  36. }else if (typeChar == 'd') {
  37. ret[i].setType(FTPFile.TYPE_DIRECTORY);
  38. }else if (typeChar == 'l') {
  39. ret[i].setType(FTPFile.TYPE_LINK);
  40. ret[i].setLink(linkedString);
  41. }else {
  42. thrownew FTPListParseException();
  43. }
  44. ...

你可能感兴趣的:(client)