如何在Java中读取CSV文件-Iterator和Decorator的案例研究

在本文中,我将讨论如何使用Apache Common CSV读取CSV(逗号分隔值)文件。 从这个案例研究中,我们将学习如何在设计模式的上下文中使用IteratorDecorator来提高不同情况下的可重用性。 但是在开始之前,我想我必须先回答两个问题。

  1. 如果有太多关于如何读取CSV文件的DIY帖子,我为什么需要第三方库?
    的确,当您使用Google“ java csv解析器”时,您将获得一些相关的帖子。 但是,即使您是初学者,也不会对这些肤浅的方法感到满意。 当然使用BufferedReaderStringsplit()将成功解析一个典型的CSV文件,但是除了使它多余之外,您将不会从中学到任何东西。 另一方面,就像我将在下面显示的那样,使用和研究Apache Common CSV将教您Design Pattern中的几个主题,例如迭代器和装饰器。
  2. 为什么选择Apache Common CSV,而不是其他?
    据我所知,Sourceforge或Google代码上还有其他几个库。 但是,如果您仔细研究他们的代码细节,请原谅我的批评,但是它们都不是灵活且易于管理的:有些过于简单,无法满足用户的各种要求;有些则过于简单。 其他人则太复杂且难以使用。 此外,我遇到的大多数人都没有商业友好型许可证。 您知道,有时确实会使用户感到恐惧。

Apache Common CSV仍在沙箱中,这意味着当前没有官方下载和稳定版本。 但是, 夜间构建可能可用。

使用迭代器隐藏基础表示

让我从一个示例CSV文件开始,其中每个记录位于单独的一行中,并以换行符分隔。 第一行是标题,其中包含与文件中的字段相对应的两个名称COL1COL2 。 文件的其余部分包含三个记录,各字段之间用逗号分隔。

COL1,COL2
a,b
c,d
e,f

使用Apache Common CSV读取此文件的代码是:

public void test() throws FileNotFoundException, IOException {CSVParser parser = new CSVParser(new FileReader("test.csv"), CSVFormat.DEFAULT.withHeader());for (CSVRecord record : parser) {System.out.printf("%s\t%s\n", record.get("COL1"), record.get("COL2"));}parser.close();
}

CSVParser用于根据指定的格式解析CSV文件。 在这里,我使用默认的CSVFormat以及设置不带参数的withHeader() 。 这样,解析器就可以将CSV文件的第一行作为标题,并使record.get("COL1")有效。 CSVParser提供了一种读取记录的迭代方式。 在这里,我们遇到了第一个设计模式Iterator 。 它提供了一种顺序访问CSV文件记录而不暴露其底层表示的方法,例如如何跳过注释行以及如何将列名映射到字段值。 对于每个记录,我们使用CSVRecord.get(String name)来按字段名称检索字段值。

CSVRecord提供了多种访问字段值的方式:按名称或按索引。 如果不确定该字段是否有值或为空, CSVRecord.isSet(String name)可以在之前调用CSVRecord.isSet(String name) 。 如果只想检查解析器是否定义了名称,则调用CSVRecord.isMapped(String name)

使用装饰器允许不同的行为

CSVFormat.DEFAULTCSVFormat.RFC4180遵循RFC4180格式。 因此,用双引号引起来的字段也可以处理,例如

"COL1","COL2"
"a","b"
"c","d"
"e","f"

在RFC4180中 ,CSV文件中的字段应以逗号分隔。 但是通常,该库可以处理任意分隔符,例如TAB或空格。 为了使代码可重复使用,该库提供了一种创建自己的CSVFormat的方法

CSVFormat format = CSVFormat.newFormat(',').withQuoteChar('"').withHeader();

上面的格式与CSVFormat.DEFAULT相同。 在这里,我们遇到了另一个设计模式Decorator ,它允许将行为静态或动态地添加到单个对象中,而不会影响同一类中其他对象的行为。 在CSVFormat的情况下,每个withXXX()方法都返回一个新的CSVFormat ,它与调用方相同,但修改了一个属性。 这里的问题可能是为什么不只返回自引用this ? 我认为这是因为后面的方法将使以下代码失败

CSVFormat format = CSVFormat.newFormat(',');
CSVFormat format1 = format.withQuoteChar('"');
CSVFormat format2 = format.withHeader();

如果仅返回thisformat1将等于format2 ,这绝对是我们现在所期望的。

CSVFormat提供了非常灵活的方式来指定CSV格式。 可以在其javadoc中找到详细信息,该文档有据可查。 我们可以设置定界符,注释开始标记,引号字符等。因此,对于以下CSV文件,其中用TAB分隔字段,并以#开头注释,

COL1    COL2
# comments
a       b
c       d
e       f

我们可以创建一个格式

CSVFormat format = CSVFormat.newFormat('\t').withCommentStart('#').withIgnoreEmptyLines(true).withNullString("").withHeader();

总之,开始使用Apache Common CSV来统一一个通用和简单的界面,以便在ASL许可下读写CSV文件。 它仍然在沙箱中,但是可以灵活地满足不同的需求。 最后,我想强调的是,阅读复杂的代码确实有助于提高编程技能。 因此,强烈建议您阅读此项目源代码,它非常简单但功能强大。

参考: 如何用Java读取CSV文件-我们的JCG合作伙伴 Peng Yifan在PGuru博客上进行的Iterator和Decorator案例研究 。

翻译自: https://www.javacodegeeks.com/2013/10/how-to-read-csv-files-in-java-a-case-study-of-iterator-and-decorator.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在本地开发环境调试微信 JS-SDK

以下篇幅将会描述不同前提下对应的调试策略,当然也有可能不是最优解,望斧正 →_→ 前言 何谓「安全域名限制」? 以微信 JS-SDK 的使用为例,每个公众号被限制最多可设置三个安全域名,且必须能被腾讯服务器所验证&#…

PHP中常用加解密方式

PHP中使用OpenSSL生成RSA公钥私钥及进行加密解密示例 加密基础 加密算法一般分为两种:对称加密算法和非对称加密算法。 对称加密 对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用同样的密匙解密&#x…

云南省农村信用社计算机岗位待遇如何,云南农村信用社薪资待遇如何?

在云南如果去存钱,相信大多数人都会把自己的小钱钱存在农村信用社而不是XX银行。在这一块风景秀丽,人美山美水美的地方,就金融行业来说云南农村信用社要是说自己差,那基本没有谁敢说自己做的好。所以在云南农信社这家企业里做一名…

小票上为啥指甲能划出印_指甲上出现竖纹,除遗传问题,或是身体在向你拉警报了,别忽视...

生活中常见女生给指甲抹上各种不同的颜色来让它变得美美的,指甲起着修饰人的形象的作用。而指甲的状况也能折射出身体的健康状态如何。每个人的指甲形态不一,有的润滑饱满,光滑平整,有月牙;有的坑坑洼洼,凸…

require.context

带表达式的 require 语句 如果你的 require参数含有表达式(expressions),会创建一个上下文(context),因为在编译时(compile time)并不清楚具体是哪一个模块被导入 require("./template/" name ".ejs");webpack 解析 require() 的…

使用JSF 2.2功能来开发可滚动,可延迟加载的Ajax数据表

这次,我想与您分享我最近从JSF 2.2功能中学到的知识。 为此,我决定创建一个简单的ajax,可滚动的延迟加载数据表。 请注意, 绝不这是相当大的库如Primefaces , RichFaces的或ICEFaces的 。 这只是为了告诉您我学到了什…

如何监视ps/查询的性能和使用

可以使用“查询管理”页面监视查询性能和使用情况。您可以获得的一些统计信息包括平均运行时、运行次数和上次运行日期。使用预定义的搜索,还可以选择要检查和报告的查询。查询管理还允许您取消当前在查询管理器和查询查看器中运行的查询,以及启用和禁用…

金融计算机怎么调成链式,FRM金融计算器使用方法

2020FRM考试计算器:想一想FRM一级考试基本上按计算器停不下来,我们就一定要买一个简单易操作的计算器,但是GARP对于FRM考生所使用的计算器是有规定的:所有参加FRM考试的考生必须使用GARP指定的计算器,如果考生在考试期…

spring 基础

作者:Spring太难链接:https://zhuanlan.zhihu.com/p/38131490来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。目录 Spring 概述 依赖注入 Spring beans Spring注解 Spring数据访问 Spring面向切面…

参数调优为什么要采样_程序员精进之路:性能调优利器--火焰图

本文主要分享火焰图使用技巧,介绍 systemtap 的原理机制,如何使用火焰图快速定位性能问题原因,同时加深对 systemtap 的理解。让我们回想一下,曾经作为编程新手的我们是如何调优程序的?通常是在没有数据的情况下依靠主…

我是这么理解Vue中的响应式系统的

遇到知识,尤其是复杂的概念,我不能类比的话,我很难接收(所以学习很差...)。在看了大神染陌同学的Vue源码解析后,我想分享一下我所类比的Vue响应式系统,您得先看他的文章(至少看他写的…

图的顺序存储(邻接矩阵存储)【摘录自严长生老师的网站】

图是表达多对多关系的一种数据结构,组成要素为顶点和连接顶点的边。 根据边有无方向可分为有向图和无向图 当边有权重时,升级为有向网和无向网 图在存储时,可采用邻接矩阵,比如下面的无向图(A)和&#xff0…

Neo4j:使隐式关系成为显式和双向关系

最近,我阅读了Michal Bachman关于 Neo4j中双向关系的文章 ,他建议对于某些关系类型,我们对关系的方向不那么感兴趣,因此可以在查询时忽略它。 他使用以下示例显示了Neo Technology和GraphAware之间的合作关系: 两家公…

复旦大学计算机学院博士生王斌,复旦大学计算机科学技术学院博士生刘鹏飞荣获...

计算机科学技术学院发布时间:2017-01-04 小字体 中字体 大字体2016年12月22日,历时七个月选拔的2016年度百度奖学金获奖者揭晓,复旦大学计算机科学技术学院2014级博士生刘鹏飞以其在“自然语言处理与深度学习”上取得的突出成绩,从国内外近百所著名高校数百位竞争者中脱颖而出,…

BZOJ3878: [Ahoi2014Jsoi2014]奇怪的计算器

BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器 Description 【故事背景】 JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写一个程序来模拟这个计算器的运算。【问题描述】JYY的计算器可以执行N条预设好的指令。每次JYY向计算器输入一个…

Deno 兼容浏览器具体指的是什么?

Deno 里面有一句描述:"Aims to be browser compatible",可以看到 Deno 的目标是兼容浏览器。那么这里的兼容浏览器到底如何是什么意思呢? 我简单谈谈我的理解吧。 首先这里的兼容性肯定不是 Deno 直接在浏览器端运行。因为 Deno …

判断按键值_「正点原子NANO STM32开发板资料连载」第十六章电容触摸按键实验...

1)实验平台:ALIENTEK NANO STM32F411 V1开发板2)摘自《正点原子STM32F4 开发指南(HAL 库版》关注官方微信号公众号,获取更多资料:正点原子第十六章电容触摸按键实验上一章,我们介绍了 STM32F4 的…

将社交登录添加到Spring MVC Web应用程序:注册和登录

本教程的第一部分描述了如何配置Spring Social 1.1.0和Spring Security 3.2.0,但它留下了两个非常重要的问题尚未解答。 这些问题是: 用户如何创建新用户帐户? 用户如何登录? 现在该弄脏我们的手并回答这些问题了。 我们的示例…

实验五 编写、调试具有多个段的程序

(1)将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题。 ①CPU执行程序,程序返回前,data段的数据为多少? 见下图d 0770:0000 000f结果。 ②CPU执行程序,程序返回前&#xff0c…