FTPClient中listFiles方法返回數組長度為‘0’


起因:最近通過FTP接收第三方客戶的日志,發現當他們的ftp服務器的文件時間為中文時:

如下格式:

rw-r----- 1 cmodftp boss3 0 7月26日 16:23 LP_OPERATION_LOG_20120417.done
-rw-r--r-- 1 boss3adm boss3 32037633 2012年4月17日 LP_OPERATION_LOG_20120417.log
-rw-r--r-- 1 boss3adm boss3 43843978 2012年5月17日 LP_OPERATION_LOG_20120517.csv
-rw-r--r-- 1 boss3adm boss3 42120155 2012年6月17日 LP_OPERATION_LOG_20120617.csv
-rw-r--r-- 1 boss3adm boss3 41001090 2012年7月17日 LP_OPERATION_LOG_20120717.csv
-rw-r--r-- 1 boss3adm boss3 45539206 2012年8月17日 LP_OPERATION_LOG_20120817.csv
-rw-r--r-- 1 boss3adm boss3 29434197 2012年9月17日 LP_OPERATION_LOG_20120917.csv
-rw-r--r-- 1 boss3adm boss3 22358774 2012年10月17日 LP_OPERATION_LOG_20121017.csv
-rw-r--r-- 1 boss3adm boss3 9104535 2012年11月17日 LP_OPERATION_LOG_20121117.csv
-rw-r--r-- 1 boss3adm boss3 13295291 2012年12月17日 LP_OPERATION_LOG_20121217.csv
-rw-r--r-- 1 boss3adm boss3 13490257 2013年1月17日 LP_OPERATION_LOG_20130117.csv
-rw-r--r-- 1 boss3adm boss3 33587905 2月17日 06:15 LP_OPERATION_LOG_20130217.csv
-rw-r--r-- 1 boss3adm boss3 24715688 3月17日 06:04 LP_OPERATION_LOG_20130317.csv
-rw-r--r-- 1 boss3adm boss3 23283526 4月17日 07:24 LP_OPERATION_LOG_20130417.csv
-rw-r--r-- 1 boss3adm boss3 27248855 5月17日 07:36 LP_OPERATION_LOG_20130517.csv
-rw-r--r-- 1 boss3adm boss3 21768020 7月17日 06:58 LP_OPERATION_LOG_20130717.csv

在接收時,無法獲取該目錄下的文件列表。

查看源代碼如下:

package org.apache.commons.net.ftp.parser;

public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl

{

private static final String REGEX =
"([bcdelfmpSs-])"
+"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s*"
+ "(\\d+)\\s+" // link count
+ "(?:(\\S+(?:\\s\\S+)*?)\\s+)?" // owner name (optional spaces)
+ "(?:(\\S+(?:\\s\\S+)*)\\s+)?" // group name (optional spaces)
+ "(\\d+(?:,\\s*\\d+)?)\\s+" // size or n,m
/*
* numeric or standard format date:
* yyyy-mm-dd (expecting hh:mm to follow)
* MMM [d]d
* [d]d MMM
* N.B. use non-space for MMM to allow for languages such as German which use
* diacritics (e.g. umlaut) in some abbreviations.
*/
//+ "((?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S{3}\\s+\\d{1,2})|(?:\\d{1,2}\\s+\\S{3}))\\s+"
// to support the date of ‘2013年2月12日’ or ‘3月17日’ ---------> kavin 21030801

//此處添加了((?:\\d{1,4}\\u5e74{1})?\\d{1,2}\\u6708{1}\\d{1,2}\\u65e5{1})支持中文日期格式
+ "(((?:\\d{1,4}\\u5e74{1})?\\d{1,2}\\u6708{1}\\d{1,2}\\u65e5{1})|(?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S{3}\\s+\\d{1,2})|(?:\\d{1,2}\\s+\\S{3}))\\s+"
/*
year (for non-recent standard format) - yyyy
or time (for numeric or recent standard format) [h]h:mm
*/
//+ "(\\d+(?::\\d+)?)\\s+"
+ "((\\d+(?::\\d+)?)\\s+)?"
+ "(\\S*)(\\s*.*)"; // the rest

}

/**
* Parses a line of a unix (standard) FTP server file listing and converts
* it into a usable format in the form of an <code> FTPFile </code>
* instance. If the file listing line doesn't describe a file,
* <code> null </code> is returned, otherwise a <code> FTPFile </code>
* instance representing the files in the directory is returned.
* <p>
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
// @Override
public FTPFile parseFTPEntry(String entry) {

FTPFile file = new FTPFile();
file.setRawListing(entry);
int type;
boolean isDevice = false;
if (matches(entry))
{
int groupCount = getGroupCnt();
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(21);
String name = group(24);
switch (groupCount)
{
// Jul 24 00:55
case 24:
if(datestr.contains("\u65e5"))
{
datestr = group(19);
name = group(23);
}
break;
default:
break;
}

String endtoken = null;
try
{
System.out.println(" ------------------------> groupCount = "+groupCount+" | datestr = "+datestr +" <-----------------------");
file.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
/* ***mod by kavin將中文時間格式轉換 2013-7-31 begin*** */
//return null; // this is a parsing failure too.
try
{
FTPTimestampParserImplExZH Zh2En = new FTPTimestampParserImplExZH();
file.setTimestamp(Zh2En.parseTimestamp(datestr));
}
catch (ParseException e1)
{
//e1.printStackTrace();
return null; // this is a parsing failure too.
}
}

// A 'whiteout' file is an ARTIFICIAL entry in any of several types of
// 'translucent' filesystems, of which a 'union' filesystem is one.

// bcdelfmpSs-
switch (typeStr.charAt(0))
{
case 'd':
type = FTPFile.DIRECTORY_TYPE;
break;
case 'e': // NET-39 => z/OS external link
type = FTPFile.SYMBOLIC_LINK_TYPE;
break;
case 'l':
type = FTPFile.SYMBOLIC_LINK_TYPE;
break;
case 'b':
case 'c':
isDevice = true;
type = FTPFile.FILE_TYPE; // TODO change this if DEVICE_TYPE implemented
break;
case 'f':
case '-':
type = FTPFile.FILE_TYPE;
break;
default: // e.g. ? and w = whiteout
type = FTPFile.UNKNOWN_TYPE;
}

file.setType(type);

int g = 4;
for (int access = 0; access < 3; access++, g += 4)
{
// Use != '-' to avoid having to check for suid and sticky bits
file.setPermission(access, FTPFile.READ_PERMISSION,
(!group(g).equals("-")));
file.setPermission(access, FTPFile.WRITE_PERMISSION,
(!group(g + 1).equals("-")));

String execPerm = group(g + 2);
if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0)))
{
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, true);
}
else
{
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, false);
}
}

if (!isDevice)
{
try
{
file.setHardLinkCount(Integer.parseInt(hardLinkCount));
}
catch (NumberFormatException e)
{
// intentionally do nothing
}
}

file.setUser(usr);
file.setGroup(grp);

try
{
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
// intentionally do nothing
}

if (null == endtoken)
{
file.setName(name);
}
else
{
// oddball cases like symbolic links, file names
// with spaces in them.
name += endtoken;
if (type == FTPFile.SYMBOLIC_LINK_TYPE)
{
int end = name.indexOf(" -> ");
// Give up if no link indicator is present
if (end == -1)
{
file.setName(name);
}
else
{
file.setName(name.substring(0, end));
file.setLink(name.substring(end + 4));
}

}
else
{
file.setName(name);
}
}
return file;
}
return null;
}

 

新增加一個FTP文件時間解析類,專門處理中文時間,轉換成正常的yyyyMMdd

public class FTPTimestampParserImplExZH extends FTPTimestampParserImpl
{
private SimpleDateFormat defaultDateFormat = new SimpleDateFormat("mm dd hh:mm");
private SimpleDateFormat recentDateFormat = new SimpleDateFormat("yyyy mm dd");

/**
* @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);
}
}

String timeDig = sb.toString();
int length = timeDig.length();
switch (length)
{
case 3:
timeDig = getToday("yyyy")+"0"+timeDig;
break;
case 4:
timeDig = getToday("yyyy")+timeDig;
break;
case 7:
timeDig = timeDig.substring(0, 4)+"0"+timeDig.substring(4);
break;
default:
break;
}

System.out.println(" ================>> formatDate_Zh2En<timeStrZh = "+timeStrZh+">|"+"<timeStr"+timeDig+">");
return timeDig;
}

private String getToday(String format)
{
if (format == null)
format = "yyyy-MM-dd HH:mm:ss";
Calendar c = Calendar.getInstance();
SimpleDateFormat ft = new SimpleDateFormat(format);
return ft.format(c.getTime());
}

/**
* 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();
int year = Integer.valueOf(timestampStr.substring(0, 4));
int month = Integer.valueOf(timestampStr.substring(4, 6));
int day = Integer.valueOf(timestampStr.substring(6, 8));
Calendar calendar = Calendar.getInstance();
calendar.set(year, month - 1, day, 0, 0, 0);
/* 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())
{
System.out.println("111111111111111111111111");
working.setTime(parsed);
working.set(Calendar.YEAR, now.get(Calendar.YEAR));
if (working.after(now))
{
working.add(Calendar.YEAR, -1);
}
}
else
{
System.out.println("22222222222222222222222");
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;
}
}

通過以上方式即可獲取列表,同時下載對應的文件。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM