赞
踩
commons-net-1.4.1.jar包中ftp应用的几点问题
一、异常:
从http://commons.apache.com/网站下载了commons-net-1.4.1包后添加到自己的工程中,调用FtpClient类的listFiles(String pathName)方法时,抛如下异常:
Exception in thread "main" java.lang.NoClassDefFoundError:org/apache/oro/text/regex/MalformedPatternException
at org.apache.commons.net.ftp.parser.RegexFTPFileEntryParserImpl. (RegexFTPFileEntryParserImpl.java:75)
at org.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl.(ConfigurableFTPFileEntryParserImpl.java:57)
at org.apache.commons.net.ftp.parser.UnixFTPEntryParser.(UnixFTPEntryParser.java:136)
at org.apache.commons.net.ftp.parser.UnixFTPEntryParser.(UnixFTPEntryParser.java:119)
at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createUnixFTPEntryParser(DefaultFTPFileEntryParserFactory.java:169)
at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFactory.java:94)
at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2358)
at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2141)
at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2188)
.................
以上异常是由于缺少辅助的包jakarta-oro-2.0.8.jar引起的,去http://commons.apache.com/网站下载该包后放入工程的lib下,并加载到classpath中,重新编译运行,OK!
二、调用FtpClient类的listFiles(String pathName)方法失效的问题:
一般是由于ftp服务器(主要是小型机)的操作系统不同语言环境的时间格式造成的,在中文环境下,文件或文件夹的时间格式为"m月d日 hh:mm"或"yyyy年m月 d",而E文环境下时间格式为"MMM d yyyy"或"MMM d HH:mm",于是,在中文环境下,ftp包中的FTPTimestampParserImpl类将时间字符串Date化时抛异常,因为commons-net-1.4.1包不支持中文。
解决办法(两种办法):
1. 将ftp服务器操作系统语言环境设为英文;
2. 修改ftp包的代码:将FTPTimestampParserImpl类进行扩展,使之支持中文
下面针对第2种解决办法来实现:
(1) 新建类FTPTimestampParserImplExZH类:
1
/**2* FTPTimestampParserImpl的扩展类,使之支持中文环境的时间格式3* Date:2007-8-154*/5packageorg.apache.commons.net.ftp.parser;67importjava.text.ParseException;8importjava.text.ParsePosition;9importjava.text.SimpleDateFormat;10importjava.util.Calendar;11importjava.util.Date;1213/**14*@authorhzwei20615* FTPTimestampParserImpl的扩展类,使之支持中文环境的时间格式16*/17publicclassFTPTimestampParserImplExZHextendsFTPTimestampParserImpl18{19privateSimpleDateFormat defaultDateFormat=newSimpleDateFormat("mm d hh:mm");20privateSimpleDateFormat recentDateFormat=newSimpleDateFormat("yyyy mm d");2122/**23 *@authorhzwei20624 * 将中文环境的时间格式进行转换25*/26privateString formatDate_Zh2En(String timeStrZh)27{28if(timeStrZh==null)29{30return"";31 }3233intlen=timeStrZh.length();34 StringBuffer sb=newStringBuffer(len);35charch='';36for(inti=0;i{38 ch=timeStrZh.charAt(i);39if((ch>='0'&&ch<='9')||ch==''||ch==':')40{41 sb.append(ch);42 }43 }4445returnsb.toString();46 }4748/**49 * Implements the one {@linkFTPTimestampParser#parseTimestamp(String) method}50 * in the {@linkFTPTimestampParser FTPTimestampParser} interface51 * according to this algorithm:52 *53 * If the recentDateFormat member has been defined, try to parse the54 * supplied string with that. If that parse fails, or if the recentDateFormat55 * member has not been defined, attempt to parse with the defaultDateFormat56 * member. If that fails, throw a ParseException.57 *58 *@seeorg.apache.commons.net.ftp.parser.FTPTimestampParser#parseTimestamp(java.lang.String)59*/60publicCalendar parseTimestamp(String timestampStr)throwsParseException61{62 timestampStr=formatDate_Zh2En(timestampStr);63 Calendar now=Calendar.getInstance();64 now.setTimeZone(this.getServerTimeZone());6566 Calendar working=Calendar.getInstance();67 working.setTimeZone(this.getServerTimeZone());68 ParsePosition pp=newParsePosition(0);6970 Date parsed=null;71if(this.recentDateFormat!=null)72{73 parsed=recentDateFormat.parse(timestampStr, pp);74 }75if(parsed!=null&&pp.getIndex()==timestampStr.length())76{77 working.setTime(parsed);78 working.set(Calendar.YEAR, now.get(Calendar.YEAR));79if(working.after(now))80{81 working.add(Calendar.YEAR,-1);82 }83 }84else85{86 pp=newParsePosition(0);87 parsed=defaultDateFormat.parse(timestampStr, pp);88//note, length checks are mandatory for us since89//SimpleDateFormat methods will succeed if less than90//full string is matched. They will also accept,91//despite "leniency" setting, a two-digit number as92//a valid year (e.g. 22:04 will parse as 22 A.D.)93//so could mistakenly confuse an hour with a year,94//if we don't insist on full length parsing.95if(parsed!=null&&pp.getIndex()==timestampStr.length())96{97 working.setTime(parsed);98 }99else100{101thrownewParseException(102"Timestamp could not be parsed with older or recent DateFormat",103 pp.getIndex());104 }105 }106returnworking;107 }108}109110111
(2)修改org.apache.commons.net.ftp.parser.UnixFTPEntryParser类的parseFTPEntry方法:
1
publicFTPFile parseFTPEntry(String entry)2{3
..4if(matches(entry))5{6 String typeStr=group(1);7 String hardLinkCount=group(15);8 String usr=group(16);9 String grp=group(17);10 String filesize=group(18);11 String datestr=group(19)+""+group(20);12 String name=group(21);13 String endtoken=group(22);1415try16{17 file.setTimestamp(super.parseTimestamp(datestr));18 }19catch(ParseException e)20{21/****mod by hzwei206 将中文时间格式转换 2007-8-15 begin****/22//return null;//this is a parsing failure too.23try24{25 FTPTimestampParserImplExZH Zh2En=newFTPTimestampParserImplExZH();26 file.setTimestamp(Zh2En.parseTimestamp(datestr));27 }28catch(ParseException e1)29{30returnnull;//this is a parsing failure too.31}32/****mod by hzwei206 将中文时间格式转换 2007-8-15 end****/33 }3435
..36 }37
JAVA中使用FTPClient上传下载
在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件、下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件。
一、上传文件
原理就不介绍了,大家直接看代码吧
/**
* Description: 向FTP服务器上传文件
* @Version1.0 Jul 27, 2008 4:31:09 PM by 崔红保(cuihongbao@d-heaven.com)创建
* @param url FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param path FTP服务器保存目录
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return 成功返回true,否则返回false
*/
publicstaticbooleanuploadFile(String url,intport,String username, String password, String path, String filename, InputStream input) {
booleansuccess =false;
FTPClient ftp = newFTPClient();
try{
intreply;
ftp.connect(url, port);//连接FTP服务器
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(username, password);//登录
reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
returnsuccess;
}
ftp.changeWorkingDirectory(path);
ftp.storeFile(filename, input);
input.close();
ftp.logout();
success = true;
} catch(IOException e) {
e.printStackTrace();
} finally{
if(ftp.isConnected()) {
try{
ftp.disconnect();
} catch(IOException ioe) {
}
}
}
returnsuccess;
}
下面我们写两个小例子:
1.将本地文件上传到FTP服务器上,代码如下:
@Test
publicvoidtestUpLoadFromDisk(){
try{
FileInputStream in=newFileInputStream(newFile("D:/test.txt"));
booleanflag = uploadFile("127.0.0.1",21,"test","test","D:/ftp","test.txt", in);
System.out.println(flag);
} catch(FileNotFoundException e) {
e.printStackTrace();
}
}
2.在FTP服务器上生成一个文件,并将一个字符串写入到该文件中
@Test
publicvoidtestUpLoadFromString(){
try{
InputStream input = newByteArrayInputStream("test ftp".getBytes("utf-8"));
booleanflag = uploadFile("127.0.0.1",21,"test","test","D:/ftp","test.txt", input);
System.out.println(flag);
} catch(UnsupportedEncodingException e) {
e.printStackTrace();
}
}
二、下载文件
从FTP服务器下载文件的代码也很简单,参考如下:
/**
* Description: 从FTP服务器下载文件
* @Version1.0 Jul 27, 2008 5:32:36 PM by 崔红保(cuihongbao@d-heaven.com)创建
* @param url FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param remotePath FTP服务器上的相对路径
* @param fileName 要下载的文件名
* @param localPath 下载后保存到本地的路径
* @return
*/
publicstaticbooleandownFile(String url,intport,String username, String password, String remotePath,String fileName,String localPath) {
booleansuccess =false;
FTPClient ftp = newFTPClient();
try{
intreply;
ftp.connect(url, port);
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(username, password);//登录
reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
returnsuccess;
}
ftp.changeWorkingDirectory(remotePath);//转移到FTP服务器目录
FTPFile[] fs = ftp.listFiles();
for(FTPFile ff:fs){
if(ff.getName().equals(fileName)){
File localFile = newFile(localPath+"/"+ff.getName());
OutputStream is = newFileOutputStream(localFile);
ftp.retrieveFile(ff.getName(), is);
is.close();
}
}
ftp.logout();
success = true;
} catch(IOException e) {
e.printStackTrace();
} finally{
if(ftp.isConnected()) {
try{
ftp.disconnect();
} catch(IOException ioe) {
}
}
}
returnsuccess;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。