起因:最近通过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 FTPFile

* instance. If the file listing line doesn't describe a file,

* null is returned, otherwise a FTPFile

* instance representing the files in the directory is returned.

*

* @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|"+"");

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;

}

}

通过以上方式即可获取列表,同时下载对应的文件。

ftp java listfiles_FTPClient中listFiles方法返回数组长度为‘0’相关推荐

  1. java中如何返回四维数组_如何从Java中的方法返回数组?

    我们可以从Java中的方法返回Java中的数组.在这里,我们有一个createArray()方法,通过从用户那里获取值来动态创建一个数组并返回创建的数组. 示例import java.util.Arr ...

  2. java 只读数组_在Java 8中创建方法引用数组的速记方法?

    我正在使用Wicket 6 / Java 8,并添加了一些简单的类,这些类利用了Java 8中的lambda功能(我知道Wicket的更高版本具有lambda支持,但我们现在不能升级).我正在创建一个 ...

  3. java返回列表_从Java 8中的方法返回列表?

    看起来你只需要元素的总和来检查它是奇数还是偶数.要知道这一点,就足以检查奇数元素的数量是奇数还是偶数. 您可以将输入拆分为奇数和偶数列表,并根据奇数列表的大小决定返回哪一个: public stati ...

  4. JAVA不同类型数组重载_java学习笔记--java中的方法与数组

    方法 完成特定功能的代码块 方法的格式 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...){ //方法体 return 返回值: } 方法的调用方式 通过方法名调用方法 根据形 ...

  5. java getitemcount_RecyclerView.Adapter中的getItemCount() 返回数组的size是出现异常?

    1.问题描述:RecyclerView.Adapter中的getItemCount() 返回数组的size是出现异常.网络用的是okhttp,数据库框架是litepal,功能是从网络上获取JSON数据 ...

  6. JAVA中返回值为字母时_LeetCode#524通过删除字母匹配到字典里最长单词-java中CompareTo方法用法以及Comparator中Compare方法返回值...

    import java.util.Collections; import java.util.Comparator; import java.util.List; /* 524. 通过删除字母匹配到字 ...

  7. JS slice()方法返回数组中指定元素

    JS slice()方法返回数组中指定元素 定义和用法 slice() 方法可从已有的数组中返回选定的元素. slice()方法可提取字符串的某个部分,并以新的字符串返回被提取的部分. 注意: sli ...

  8. java反射 数组类,乐字节Java反射之三:方法、数组、类加载器和类的生命周期

    继续讲述Java反射之三:方法.数组.类加载器 一.方法 获取所有方法(包括父类或接口),使用Method即可. public static void test() throwsException { ...

  9. Java快速入门学习笔记9 | Java语言中的方法

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

最新文章

  1. 机器人抓取汇总|涉及目标检测、分割、姿态识别、抓取点检测、路径规划
  2. php mysql 编程原理_PHP开发的原理及优势介绍
  3. basis--IMG后台如何显示事务码(How to display IMG's Tcode)
  4. 第七章 控制PL/SQL错误
  5. ASCII可显示字符
  6. [vue] 说说你对SPA单页面的理解,它的优缺点分别是什么?
  7. python实验题_python实验二
  8. easyvision视觉软件 源码_一对一直播源码都有哪些独具一格的优势?
  9. spring cloud服务发现注解之@EnableDiscoveryClient与@EnableEurekaClient 1
  10. 推动Windows的限制:虚拟内存
  11. QQ在线客服聊天功能
  12. 真实经历,说一说本人苹果ipad mini2官方799元以旧换新真实操作
  13. latex引用文献,带DOI
  14. DGPS与RTK的区别
  15. 87键盘怎么用小键盘功能
  16. Android 截屏实现、屏幕截图、MediaProjection、ImageReader
  17. 兄弟连 40 期 临行时刻
  18. OSChina 周一乱弹 —— 鱼生不值得
  19. Docker快速搭建EKL
  20. forest_train训练文件的生成代码

热门文章

  1. springboot 和 js (vue) 实现SM3加密 防篡改
  2. 云计算平台为什么是必需的
  3. Linux 的chmod权限数字777、755、644代表什么?
  4. 【Python入门】Python的Dict容器一
  5. PMP一模考试错题集+解析 之 人员
  6. 互联网到底怎么连接的?一张图告诉你
  7. 怎么用计算机自己做动画片,大师为你详解动画怎么制作
  8. 软通动力、海辉、文思以及金融外包
  9. 新富人群的快速壮大,急需金融在线直播提供更高效和广泛的服务
  10. 解决sourcetree特别卡的问题