Java – 解析分隔文件并查找列数据类型

是否可以解析分隔文件并查找列数据类型? 例如

分隔文件:

Email,FirstName,DOB,Age,CreateDate test@test1.com,Test User1,20/01/2001,24,23/02/2015 14:06:45 test@test2.com,Test User2,14/02/2001,24,23/02/2015 14:06:45 test@test3.com,Test User3,15/01/2001,24,23/02/2015 14:06:45 test@test4.com,Test User4,23/05/2001,24,23/02/2015 14:06:45 

输出:

 Email datatype: email FirstName datatype: Text DOB datatype: date Age datatype: int CreateDate datatype: Timestamp 

这样做的目的是读取分隔文件并动态构造表创建查询并将数据插入该表。

我尝试使用apachevalidation器,我相信我们需要解析整个文件以确定每个列的数据类型。

编辑:我尝试过的代码:

 CSVReader csvReader = new CSVReader(new FileReader(fileName),','); String[] row = null; int[] colLength=(int[]) null; int colCount = 0; String[] colDataType = null; String[] colHeaders = null; String[] header = csvReader.readNext(); if (header != null) { colCount = header.length; } colLength = new int[colCount]; colDataType = new String[colCount]; colHeaders = new String[colCount]; for (int i=0;i<colCount;i++){ colHeaders[i]=header[i]; } int templength=0; String tempType = null; IntegerValidator intValidator = new IntegerValidator(); DateValidator dateValidator = new DateValidator(); TimeValidator timeValidator = new TimeValidator(); while((row = csvReader.readNext()) != null) { for(int i=0;i colLength[i] ? templength : colLength[i]; if(colHeaders[i].equalsIgnoreCase("email")){ logger.info("Col "+i+" is Email"); } else if(intValidator.isValid(row[i])){ tempType="Integer"; logger.info("Col "+i+" is Integer"); } else if(timeValidator.isValid(row[i])){ tempType="Time"; logger.info("Col "+i+" is Time"); } else if(dateValidator.isValid(row[i])){ tempType="Date"; logger.info("Col "+i+" is Date"); } else { tempType="Text"; logger.info("Col "+i+" is Text"); } logger.info(row[i].length()+""); } 

不确定这是否是最好的方法,任何正确方向的指针都会有所帮助

如果您希望自己编写而不是使用第三方库,那么最简单的机制可能是为每种数据类型定义一个正则表达式,然后检查所有字段是否满足它。 这里有一些示例代码可以帮助您入门(使用Java 8)。

 public enum DataType { DATETIME("dd/dd/dddd dd:dd:dd"), DATE("dd/dd/dddd", EMAIL("\\w+@\\w+"), TEXT(".*"); private final Predicate tester; DateType(String regexp) { tester = Pattern.compile(regexp).asPredicate(); } public static Optional getTypeOfField(String[] fieldValues) { return Arrays.stream(values()) .filter(dt -> Arrays.stream(fieldValues).allMatch(dt.tester) .findFirst(); } } 

请注意,这取决于枚举值的顺序(例如,测试日期之前的日期时间)。

是的,这是可能的,你必须先解析整个文件。 为每种数据类型制定一套规则。 迭代列中的每一行。 如果该列中的行违反该数据类型的规则,则每个列都具有每种数据类型,并取消数据类型。 迭代列后,检查为列保留的数据类型。 例如。 假设我们有两个数据类型integer和text …整数规则…它必须只包含数字0-9并且可以以’ – ‘开头。 文字可以是任何东西。

我们专栏:

 345 -1ab 123 

整数数据类型将被第二行删除,因此它将是文本。 如果第二行只是-1那么你将留下整数和文本,所以它将是整数,因为文本永远不会被删除,因为我们的规则说文本可以是任何东西……如果你离开,你基本上不必检查文本没有其他数据类型答案是文本。 希望这能回答你的问题