Reading and Writing CSVs in Java with OpenCSV
介绍
这是专门针对Java CSV读写库的简短系列的最后一篇文章,也是上一篇文章的直接续篇-使用Apache Commons CSV的Java CSV读写。
打开CSV
OpenCSV是最简单易懂的CSV解析器之一,它使用标准的
就像Apache Commons CSV一样,OpenCSV具有Apache 2.0许可证。 在下载并决定是否使用OpenCSVs解析器之前,您可以浏览源代码和Java文档,甚至查看其git存储库中包含的JUnit测试套件。
OpenCSV也包含在MVNRepository中,使依赖关系管理变得简单明了。
OpenCSV没有像Apache Commons CSV一样广泛的预定义格式。 它依赖于两个解析器:
CSVParser-在OpenCSV中定义的原始解析器。 这适用于大多数简单的解析实例,但是如果记录中定义了转义字符,则失败。
RFC4180Parser-与Apache Commons CSV中的
使用OpenCSV读取CSV
用OpenCSV读取CSV比使用Apache Commons CSV读取CSV更快,因为在使用
OpenCSV有两种用于读取CSV的对象类型-CSVReader及其子类CSVReaderHeaderAware。
要遍历CSV文件中的每条记录,其中
1 2 3 4 | CSVReader csvReader = new CSVReader (new InputStreamReader(csvFile.getInputStream())); while ((record = csvReader.readNext()) != null) { // do something } |
如果CSV由逗号以外的字符分隔,则可以改用两参数构造函数,并指定要使用
例如,如果CSV包含制表符分隔的值,则可以按以下方式初始化
1 |
OpenCSV还有一种解析CSV文件的更复杂的方法,其中涉及实现bean来映射CSV中的字段,然后使用注释通过基于标题的注释或基于位置的注释来标识记录的类型。
这有帮助,因为它允许将CSV记录作为通用数据集而不是单个字段的集合进行处理。
如果正在处理的文件的标题名称一致,则可以使用
例如我们的树数据集:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class Trees { @CSVBindByName private int index; @CSVBindByName private int girth; @CSVBindByName private int height; @CSVBindByName private int volume; public int getIndex() { return this.index; } public void setIndex(int newIndex) { this.index = newIndex; } ... } |
只要您的CSV文件在我们的类声明中包含一个以变量名命名的头,OpenCSV便可以解析数据并将其读入相应的元素,并自动处理类型转换:
1 | List<Trees> treeParser = new CSVToBeanBuilder(FileReader("somefile.csv")).withType(Trees.class).build().parse(); |
可以在需要的地方将验证添加到getter和setter方法中,并且可以通过在注释上设置
如果标题名称与变量名称略有不同,则也可以在注释中设置String。 在我们的示例中,当列名不同时,能够映射标头名称的功能非常有用,因为我们的实际数据集包含字段的度量单位,以及标准Java变量名称中不允许的空格和标点符号。
在这种情况下,可以使用注释指定标志和映射:
1 2 3 4 | ... @CSVBindByName (column ="Girth (in)", required = true) private int girth; ... |
如果CSV文件没有标题,则可以按列位置与
请记住,OpenCSV位置从0开始:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Trees{ @CSVBindByPosition(position = 0, required = true) private int index; @CSVBindByPosition(position = 1, required = true) private int girth; @CSVBindByPosition(position = 2) private int height; @CSVBindByPosition(position = 3) private int volume; } |
如果要处理更复杂的场景,则可以使用MappingStrategy接口实现一个类,并定义适合您的解析场景的转换或映射架构。
使用OpenCSV编写CSV
在将数据写入CSV文件时,OpenCSV比Apache Commons CSV具有更多选项。 它允许您从字符串数组中写入,或从对象列表中写入。
从对象列表进行写入需要事先初始化和声明对象。 为了使事情简单,让我们考虑使用字符串数组。
要使用字符串数组中的数据生成CSV文件,请执行以下操作:
1 2 3 4 | CSVWriter csvWriter = new CSVWriter(new FileWriter("new.csv"), ','); String[] records ="Index.Girth.Height.Volume".split("."); csvWriter.writeNext(records); csvWriter.close(); |
OpenCSV的概念是CSV不仅是逗号分隔的值; 它允许您定义要在文件中使用哪个定界符作为
同样,在定义String数组时,您可能会发现声明一个String然后基于定界符将其分隔为多个值很有用。 当您需要将选定的数据行子集从一个CSV或数据库文件复制到另一个时,此功能特别有用。
初始化
对于特定的用例,还有一些其他参数:
您可以构造包含所有可选参数的
1 2 |
例如,在声明之后:
1 2 3 4 5 | CSVWriter.DEFAULT_SEPARATOR =","; CSVWriter.DEFAULT_QUOTE_CHARACTER ="'"; CSVWriter.DEFAULT_ESCAPE_CHARACTER ="/"; CSVWriter.DEFAULT_LINE_END =" "; |
您可以使用:
1 | CSVWriter csvWriter = new CSVWriter(new FileWriter("new.csv"), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END); |
如果未在构造函数中明确定义值,则可以使用默认值使用OpenCSV并直接调用:
1 |
因此,如果您的数据包含带有用户名和地址的行,例如:JohnDoe,19/2,ABC Street,Someplace,则您需要使用的实际字符串格式是" JohnDoe"," 19 // 2 /,ABC Street /,Someplace"。
结论
OpenCSV是最简单易懂的CSV解析器之一,它使用标准的
在Core Java中读写CSV
使用Apache Commons CSV用Java读写CSV