在Java中的CSVparsing – 工作示例..?

我想写一个学校java项目的程序来parsing一些CSV,我不知道。 我知道每列的数据types – 虽然我不知道分隔符。

我甚至不知道如何解决的问题是parsingDate或甚至DateTime列。 他们可以是多种格式之一。

我发现很多库,但没有线索,这是我的需求最好的: http : //opencsv.sourceforge.net/ http://www.csvreader.com/java_csv.php http://supercsv.sourceforge.net/ http ://flatpack.sourceforge.net/

问题是我是一个总的java初学者。 恐怕不是那些图书馆可以做我所需要的,或者说我不能说服他们去做。

我敢打赌,这里有很多人有代码示例,可以让我立即开始为我所需要的:

  • 在列中自动分割(分隔符未知,Columypes类已知)
  • 投到Columntype(应该处理$,%等)
  • 将date转换为Javadate或日历对象

通过电子邮件获取尽可能多的代码样本将是很好的。

非常感谢! 如

使用中存在严重的问题

String[] strArr=line.split(","); 

为了parsingCSV文件,那是因为在数据值中可以有逗号,在这种情况下,你必须引用它们,忽略引号之间的逗号。

有一个非常简单的方法来parsing这个:

 /** * returns a row of values as a list * returns null if you are past the end of the input stream */ public static List<String> parseLine(Reader r) throws Exception { int ch = r.read(); while (ch == '\r') { //ignore linefeed chars wherever, particularly just before end of file ch = r.read(); } if (ch<0) { return null; } Vector<String> store = new Vector<String>(); StringBuffer curVal = new StringBuffer(); boolean inquotes = false; boolean started = false; while (ch>=0) { if (inquotes) { started=true; if (ch == '\"') { inquotes = false; } else { curVal.append((char)ch); } } else { if (ch == '\"') { inquotes = true; if (started) { // if this is the second quote in a value, add a quote // this is for the double quote in the middle of a value curVal.append('\"'); } } else if (ch == ',') { store.add(curVal.toString()); curVal = new StringBuffer(); started = false; } else if (ch == '\r') { //ignore LF characters } else if (ch == '\n') { //end of a line, break out break; } else { curVal.append((char)ch); } } ch = r.read(); } store.add(curVal.toString()); return store; } 

这种方法有很多优点。 请注意,每个字符都被正确触及一次。 没有前面的读数,推回缓冲区等等。没有向前search到行末,然后在parsing之前复制行。 此parsing器纯粹从stream中工作,并创build每个string值一次。 它适用于标题行和数据行,您只需处理与之相关的返回列表。 你给它一个阅读器,所以底层的stream已经被转换为使用你select的任何编码的字符。 stream可以来自任何来源:文件,HTTPpost,HTTP获取,并直接parsingstream。 这是一个静态的方法,所以没有对象来创build和configuration,当这个返回时,没有内存被占用。

你可以find关于这个代码的完整的讨论,以及为什么这个方法在我的博客文章中优先考虑的主题: 唯一你需要的CSV文件 。

您还拥有Apache Commons CSV库,也许它可以满足您的需求。 看指南 。 更新至2014-11版本1.1。

此外,为了万无一失的版本,我认为你需要自己编写代码…通过SimpleDateFormat你可以select你的格式,并指定各种types,如果Date不像你的任何预想的types,它不是是date。

我的方法不是从编写自己的API开始。 生活太短暂,还有更紧迫的问题需要解决。 在这种情况下,我通常会:

  • find一个似乎做我想要的图书馆。 如果不存在, 那么执行它。
  • 如果一个库确实存在,但是我不确定它是否适合我的需要,可以在它周围编写一个精简的适配器API,这样我就可以控制它的调用方式。 适配器API表示需要的API,并将这些调用映射到基础API。
  • 如果库不合适,我可以在适配器API(无论是另一个开放源代码或我自己写的东西)下交换另一个,而不会影响调用者。

从某人已经写的东西开始。 赔率是,它会做你想要的。 如有必要,您随时可以自行编写。 OpenCSV是一个很好的起点。

您可能需要查看此规范的CSV。 请记住,没有官方认可的规范。

如果你现在没有分隔符,就不可能做到这一点,所以你必须找出答案。 如果你可以对文件进行手动检查,你应该很快就能看到它是什么,并在你的程序中硬编码。 如果分隔符可以改变,你唯一的希望就是能够从已知数据的格式中推断出来。 当Excel导入CSV文件时,可以让用户select分隔符,这也是一个您可以使用的解决scheme。

大约5年前,我不得不使用csvparsing器。 似乎至less有两个csv标准: http : //en.wikipedia.org/wiki/Comma-separated_values和什么微软在Excel中。

我发现这个libaray既吃: http : //ostermiller.org/utils/CSV.html ,但afaik,它没有办法推断什么样的数据types的列。

我同意@Brian Clapper。 我已经使用SuperCSV作为parsing器,虽然我有混合的结果。 我喜欢它的多function性,但在我自己的csv文件中有一些情况,我还没有能够调和“尚”。 我对这个产品有信心,并且会推荐它 – 我毫无疑问地错过了一些简单的事情,我正在自己实现。

SuperCSV可以将列parsing为各种格式,在列上进行编辑等。值得一看。 它也有例子,易于理解。

我唯一的限制是捕捉一个“空”列,并将其parsing为一个整数或可能是一个空白等。我得到空指针错误,但javadocsbuild议每个cellProcessor首先检查空值。 所以,我现在首先责备自己。 🙂

无论如何,看看SuperCSV。 http://supercsv.sourceforge.net/

至less你需要知道列分隔符。

基本上你需要逐行阅读文件。

然后,您将需要按分隔符分隔每行,例如逗号(CSV代表逗号分隔的值),

 String[] strArr=line.split(","); 

这将把它变成一个string数组,然后你可以操纵,例如

 String name=strArr[0]; int yearOfBirth = Integer.valueOf(strArr[1]); int monthOfBirth = Integer.valueOf(strArr[2]); int dayOfBirth = Integer.valueOf(strArr[3]); GregorianCalendar dob=new GregorianCalendar(yearOfBirth, monthOfBirth, dayOfBirth); Student student=new Student(name, dob); //lets pretend you are creating instances of Student 

您将需要为每一行执行此操作,以便将此代码包装到while循环中。 (如果您不知道分隔符,只需在文本编辑器中打开该文件。)

我build议你首先把你的任务分解成它的组成部分。

  1. 从CSV读取string数据
  2. 将string数据转换为适当的格式

一旦你这样做,它应该是相当简单的使用你链接到的一个库(这肯定会处理任务#1)。 然后遍历返回的值,并将每个string值转换/转换为所需的值。

如果问题是如何将string转换为不同的对象,将取决于您开始的格式,以及您想要结束的格式。

例如,DateFormat.parse()将从string中parsingdate。 请参阅SimpleDateFormat快速构build特定string表示的DateFormat。 Integer.parseInt()将从string中删除整数。

货币,你必须决定如何捕捉它。 如果你想只捕获一个浮点数,那么Float.parseFloat()就可以做到这一点(只要在parsing它之前使用String.replace()去除所有的$和逗号)。 或者你可以parsing成一个BigDecimal(所以你没有舍入问题)。 货币处理可能有更好的类别(我不这么做,所以不熟悉JDK的这个领域)。

编写你自己的parsing器很有趣,但是可能你应该看看Open CSV 。 它提供了多种访问CSV的方式,并允许生成CSV。 它确实处理逃生。 正如另一篇文章中提到的,Apache Commons中也有一个CSVparsing库,但还没有发布。