原文地址:http://411431586.blog.51cto.com/4043583/746274/
ommons-net3.0是apache公司的开源jar包, 我使用它来对一台linux中文操作系统电脑进行ftp连接, 几经修改后, 最后总结如下:
1. 操作系统的配置
在ftpClient.login(..)成功后, 调用
ftpClient.configure(new FTPClientConfig(ftpClient.getSystemType()));
2.中文乱码问题的解决
ftpClient = new FTPClient();
ftpClient.setControlEncoding("GBK");
3.FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态的解决
在执行FTPClient.listFiles()或者FTPClient.retrieveFile()方法前调用ftpClient.enterLocalPassiveMode();
这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。原文链接http://lgclf.blog.163.com/blog/static/384452222011913114428161/
4.listFiles()返回为空的解决
一般是由于ftp服务器(主要是小型机)的操作系统不同语言环境的时间格式造成的,在中文环境下,文件或文件夹的时间格式为"m月d日 hh:mm"或"yyyy年m月 d",而E文环境下时间格式为"MMM d yyyy"或"MMM d HH:mm",于是,在中文环境下,ftp包中的FTPTimestampParserImpl类将时间字符串Date化时抛异常,因为commons-net包不支持中文。
解决办法(两种办法):
1. 将ftp服务器操作系统语言环境设为英文;
2. 修改ftp包的代码:将FTPTimestampParserImpl类进行扩展,使之支持中文
下面针对第2种解决办法来实现:
(1) 新建类FTPTimestampParserImplExZH类:
/**
* FTPTimestampParserImpl的扩展类,使之支持中文环境的时间格式
* Date:2007-8-15
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* @author hzwei206
* FTPTimestampParserImpl的扩展类,使之支持中文环境的时间格式
*/
public class FTPTimestampParserImplExZH extends FTPTimestampParserImpl
{
private SimpleDateFormat defaultDateFormat = new SimpleDateFormat("mm d hh:mm");
private SimpleDateFormat recentDateFormat = new SimpleDateFormat("yyyy mm d");
/**
* @author hzwei206
* 将中文环境的时间格式进行转换
*/
private String formatDate_Zh2En(String timeStrZh)
{
if (timeStrZh == null)
{
return "";
}
int len = timeStrZh.length();
StringBuffer sb = new StringBuffer(len);
char ch = ' ';
for (int i = 0;i < len;i++)
{
ch = timeStrZh.charAt(i);
if ((ch >= '0' && ch <= '9') || ch == ' ' || ch == ':')
{
sb.append(ch);
}
}
return sb.toString();
}
/**
* Implements the one {@link FTPTimestampParser#parseTimestamp(String) method}
* in the {@link FTPTimestampParser FTPTimestampParser} interface
* according to this algorithm:
*
* If the recentDateFormat member has been defined, try to parse the
* supplied string with that. If that parse fails, or if the recentDateFormat
* member has not been defined, attempt to parse with the defaultDateFormat
* member. If that fails, throw a ParseException.
*
* @see org.apache.commons.net.ftp.parser.FTPTimestampParser#parseTimestamp(java.lang.String)
*/
public Calendar parseTimestamp(String timestampStr) throws ParseException
{
timestampStr = formatDate_Zh2En(timestampStr);
Calendar now = Calendar.getInstance();
now.setTimeZone(this.getServerTimeZone());
Calendar working = Calendar.getInstance();
working.setTimeZone(this.getServerTimeZone());
ParsePosition pp = new ParsePosition(0);
Date parsed = null;
if (this.recentDateFormat != null)
{
parsed = recentDateFormat.parse(timestampStr, pp);
}
if (parsed != null && pp.getIndex() == timestampStr.length())
{
working.setTime(parsed);
working.set(Calendar.YEAR, now.get(Calendar.YEAR));
if (working.after(now))
{
working.add(Calendar.YEAR, -1);
}
}
else
{
pp = new ParsePosition(0);
parsed = defaultDateFormat.parse(timestampStr, pp);
// note, length checks are mandatory for us since
// SimpleDateFormat methods will succeed if less than
// full string is matched. They will also accept,
// despite "leniency" setting, a two-digit number as
// a valid year (e.g. 22:04 will parse as 22 A.D.)
// so could mistakenly confuse an hour with a year,
// if we don't insist on full length parsing.
if (parsed != null && pp.getIndex() == timestampStr.length())
{
working.setTime(parsed);
}
else
{
throw new ParseException(
"Timestamp could not be parsed with older or recent DateFormat",
pp.getIndex());
}
}
return working;
}
}
(2) 修改org.apache.commons.net.ftp.parser.UnixFTPEntryParser类的parseFTPEntry方法:
public FTPFile parseFTPEntry(String entry)
{
........
if (matches(entry))
{
String typeStr = group(1);
String hardLinkCount = group(15);
String usr = group(16);
String grp = group(17);
String filesize = group(18);
String datestr = group(19) + " " + group(20);
String name = group(21);
String endtoken = group(22);
try
{
file.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
/* ***mod by hzwei206 将中文时间格式转换 2007-8-15 begin*** */
//return null; // this is a parsing failure too.
try
{
FTPTimestampParserImplExZH Zh2En = new FTPTimestampParserImplExZH();
file.setTimestamp(Zh2En.parseTimestamp(datestr));
}
catch (ParseException e1)
{
return null; // this is a parsing failure too.
}
/* ***mod by hzwei206 将中文时间格式转换 2007-8-15 end*** */
}
.................
}