fastCSV实现csv文件内容的读取和生成

编程入门 行业动态 更新时间:2024-10-23 10:23:38

fastCSV实现csv<a href=https://www.elefans.com/category/jswz/34/1771438.html style=文件内容的读取和生成"/>

fastCSV实现csv文件内容的读取和生成

   这两天需要做一个将CSV文件内容上传至数据库中,进行持久化,我的思路是先进行读取出来,然后进行一行一行插入数据库中。这种思路目前来说可能没问题,因为涉及的数据较少,如果涉及较多的数据可能就会出现加载过慢的问题,那么就需要做代码优化。
   我的CSV文件是通过爬虫从第三方数据库中爬取得到的,里面的内容格式也是各种各样。因为自己还年轻,就直接想到了以流的形式进行读取。代码如下:

InputStreamReader isr = new InputStreamReader(new FileInputStream(path), "UTF-8");BufferedReader reader = new BufferedReader(isr);int i = 0;int a = 0;try {String line = null;while((line=reader.readLine())!=null){String[] item = line.split(",",-1);//CSV格式文件为逗号分隔符文件,这里根据逗号切分System.out.println("长度:"+item.length);String str = item[1];//item[1]为价格,且为字符串,将字符串中的小数进行提取出来// 控制正则表达式的匹配行为的参数(小数)Pattern p = Patternpile("(\\d+\\.\\d+)");//Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例.Matcher m = p.matcher(str);//m.find用来判断该字符串中是否含有与"(\\d+\\.\\d+)"相匹配的子串if (m.find()) {//如果有相匹配的,则判断是否为null操作//group()中的参数:0表示匹配整个正则,1表示匹配第一个括号的正则,2表示匹配第二个正则,在这只有一个括号,即1和0是一样的str = m.group(1) == null ? "" : m.group(1);} else {//如果匹配不到小数,就进行整数匹配p = Patternpile("(\\d+)");m = p.matcher(str);if (m.find()) {//如果有整数相匹配str = m.group(1) == null ? "" : m.group(1);} else {//如果没有小数和整数相匹配,即字符串中没有整数和小数,就设为空str = "";}}System.out.println("我是:"+str);DataInfo dataInfo=new DataInfo();System.out.println("item的长度:"+item.length);//将英文逗号转换成中文逗号System.out.println("原始名字:"+item[0]);String b = ",";String str0 = item[0].replaceAll(",",b);System.out.println("item[0]:"+str0);System.out.println("item[1]:"+str);System.out.println("item[2]:"+item[2]);System.out.println("item[3]:"+item[3]);if (item[2].length() == 0){item[2] = "0";}if (item[3].length() == 0){item[3] = "0";}if (str.length() == 0){str = "0";}dataInfo.setName(str0);dataInfo.setPrice(str);dataInfo.setLatitude(item[2]);dataInfo.setLongitude(item[3]);dataInfo.setCreateDate(current);System.out.println("DataInfo的值:"+dataInfo);String[] split = fileName.split("-");System.out.println("split444:"+split[1]);//取第二个值if (split[1].equals("newhouse")){System.out.println("hahahaha1111");i = intoMapper.intoNewsMapper(dataInfo);a=a+1;}else if (split[1].equals("secondhouse")){i = intoMapper.intoSecondMapper(dataInfo);a=a+1;}else if (split[1].equals("rentinghouse")){i = intoMapper.intoRentMapper(dataInfo);a=a+1;}}}finally {reader.close();}

   大致思路就是通过InputStreamReader isr = new InputStreamReader(new FileInputStream(path), "UTF-8"); BufferedReader reader = new BufferedReader(isr)以流的形式进行全部读取,然后再通过循环行line=reader.readLine()进行遍历出来,然后再进行将每行的数据分割出来,插入到数据库中。问题就出现在行分割上面,因为是通过爬虫从第三方爬取出来的数据,格式完全不一样,有换行啦,有英文逗号啦,反正就是不可预测的各种格式,本身没办法预测更不要说进行处理这些数据了。当遇到换行问题时还好进行处理,遇到从一段文字中提取出来小数或者整数的时候也好进行处理,最难的是遇到英文逗号“,”了是最难处理的,英文你读取的数据本身每一列隔开就是用英文逗号分割开来的,读取后的内容如下图所示:

整租·山海梧桐 1室1厅 南/北,2750 元/月,22.561189,114.2286
整租·鸿荣源·壹城中心第八区 1室1厅 南,1820 元/月,22.6527136689,114.0360039841
整租·龙光玖云著 2室1厅 南,2800 元/月,22.685514,114.337256
整租·共和花园 1室0厅 南,1350 元/月,22.654156577768,114.04290481474
整租·茂业城 1室1厅 东南,1800 元/月,22.617428,114.140558
整租·向南一区 1室0厅 东南,1699 元/月,22.628218357484,114.04349583641
整租·锦城星苑 2室1厅 北,2200 元/月,22.751925445789,114.2864754459
整租·光明1号 4室2厅 东南,3000 元/月,22.740888,113.935798
整租·财富城 3室2厅 东南,2000 元/月,22.708919,114.346404
整租·百合盛世二期 3室1厅 西北,1800 元/月,22.750213,114.244653
整租·麓园 4室2厅 东南,2000 元/月,22.73853,114.22597
整租·军裕公寓 1室0厅 东,1980 元/月,22.601874,113.855116
整租·宏发雍景城 2室2厅 南/北,3800 元/月,22.785978,113.912478
整租·元芬花园 1室0厅 东南/南/西南,1299 元/月,22.660840985621,114.00942180444
整租·奥园峯荟 2室2厅 复式 西南,3200 元/月,22.771239,113.904964
整租·又一城 2室2厅 东南/南,1800 元/月,22.731801,114.220185
整租·茂业城 1室0厅 西北,1800 元/月,22.617428,114.140558
整租·茂业城 1室1厅 东南,2000 元/月,22.617428,114.140558
合租·深业新岸线三期 1居室 西南卧,1900 元/月,22.565182,113.879114
整租·德兴城花园 1室1厅 南/西南,2300 元/月,22.614861,114.120201
合租·麟恒中心广场一期 3居室 东南卧,1700 元/月,22.643806,114.19315

   你看文件内容中有英文逗号,读取的内容列于列之间又是通过“,”进行分割的,你也不知道文件内容中何时出来英文逗号。当时第一反应是把所有的内容中的逗号全部replaceAll()替换为中文逗号,但是你要直接替换,那就出现把列与列之间的英文逗号也进行替换,因此不可行;当时想到先进行分割进行替换,写了之后还进行报错,最后想起来分割后替换已经晚了,因为文件内容中的英文逗号已经进行分割,所以这种方式还是失败的。最后问了老大,给了个思路,利用fastCSV工具进行读取文件。
   下面讲下怎么使用fastCSV这个工具:
首先导入fastCSV依赖:

<dependency><groupId>de.siegmar</groupId><artifactId>fastcsv</artifactId><version>1.0.3</version>
</dependency>

然后是代码实现

CsvReader csvReader = new CsvReader();CsvReader fileReader = new CsvReader();CsvContainer csvFile = fileReader.read(file, Charset.forName("UTF-8"));if(csvFile!=null){for (CsvRow rowfiles : csvFile.getRows()) {String str = rowfiles.getField(1);//item[1]为价格,且为字符串,将字符串中的小数进行提取出来// 控制正则表达式的匹配行为的参数(小数)Pattern p = Patternpile("(\\d+\\.\\d+)");//Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例.Matcher m = p.matcher(str);//m.find用来判断该字符串中是否含有与"(\\d+\\.\\d+)"相匹配的子串if (m.find()) {//如果有相匹配的,则判断是否为null操作//group()中的参数:0表示匹配整个正则,1表示匹配第一个括号的正则,2表示匹配第二个正则,在这只有一个括号,即1和0是一样的str = m.group(1) == null ? "" : m.group(1);} else {//如果匹配不到小数,就进行整数匹配p = Patternpile("(\\d+)");m = p.matcher(str);if (m.find()) {//如果有整数相匹配str = m.group(1) == null ? "" : m.group(1);} else {//如果没有小数和整数相匹配,即字符串中没有整数和小数,就设为空str = "";}}String a2 = rowfiles.getField(2);String a3 = rowfiles.getField(3);if (rowfiles.getField(2).length() == 0){a2 = "0";}if (rowfiles.getField(3).length() == 0){a3 = "0";}if (str.length() == 0){str = "0";}DataInfo dataInfo=new DataInfo();dataInfo.setName(rowfiles.getField(0));dataInfo.setPrice(str);dataInfo.setLatitude(a2);dataInfo.setLongitude(a3);String[] split = fileName.split("-");//取第二个值if (split[1].equals("newhouse")){i = intoMapper.intoNewsMapper(dataInfo);a=a+1;}else if (split[1].equals("secondhouse")){i = intoMapper.intoSecondMapper(dataInfo);a=a+1;}else if (split[1].equals("rentinghouse")){i = intoMapper.intoRentMapper(dataInfo);a=a+1;}}}

上面是我的代码,下面给大家介绍一下使用它的三种方式:
第一种:

public static List<ResultInfo> csvReadOperation() throws IOException {Date currentTime = new Date();SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");String dateString = formatter.format(currentTime);System.out.println("startTime:"+dateString);File file = new File("/Users/xxx/Desktop/testCSVReader.csv");CsvReader csvReader = new CsvReader();csvReader.setContainsHeader(true); //表示文件包含表头List<ResultInfo> listResultInfo = new ArrayList<>();CsvContainer csv = csvReader.read(file, StandardCharsets.UTF_8);for (CsvRow row : csv.getRows()) {if (row.getOriginalLineNumber() != 1) { //同样是为了去掉表头ResultInfo resultInfo = new ResultInfo();resultInfo.setUserId(row.getField(0));resultInfo.setUserPhone(row.getField(1));resultInfo.setUserName(row.getField(2));resultInfo.setRegistTime(row.getField(3));resultInfo.setUserlevel(row.getField(4));resultInfo.setAppName(row.getField(5));listResultInfo.add(resultInfo);}}return listResultInfo;}

第二种方式:有时候文件中包含空行,如果想跳过空行,需要设置属性

public static List<ResultInfo> csvReadOperation1() throws IOException {Date currentTime = new Date();SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");String dateString = formatter.format(currentTime);System.out.println("startTime:"+dateString);File file = new File("/Users/fengyanjie/Desktop/test1CSVReader.csv");CsvReader csvReader = new CsvReader();csvReader.setContainsHeader(true);csvReader.setSkipEmptyRows(true);//设置跳过空行CsvContainer csv = csvReader.read(file, StandardCharsets.UTF_8);List<ResultInfo> listResultInfo = new ArrayList<>();System.out.println("文件list大小:"+csv.getRows().size());for (CsvRow row : csv.getRows()) {if (row.getOriginalLineNumber() != 1 && "" !=row.getFields().get(0)) {ResultInfo resultInfo = new ResultInfo();resultInfo.setUserId(row.getField(0));resultInfo.setUserPhone(row.getField(1));resultInfo.setUserName(row.getField(2));resultInfo.setRegistTime(row.getField(3));resultInfo.setUserlevel(row.getField(4));resultInfo.setAppName(row.getField(5));listResultInfo.add(resultInfo);}}return listResultInfo;}

第三种:

public static List<ResultInfo> csvReadOperation2() throws IOException {Date currentTime = new Date();SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");String dateString = formatter.format(currentTime);System.out.println("startTime:"+dateString);File file = new File("/Users/fengyanjie/Desktop/test1CSVReader.csv");CsvReader csvReader = new CsvReader();List<ResultInfo> listResultInfo = new ArrayList<>();try (CsvParser csvParser = csvReader.parse(file, StandardCharsets.UTF_8)) {CsvRow row;while ((row = csvParser.nextRow()) != null) {ResultInfo resultInfo = new ResultInfo();resultInfo.setUserId(row.getField(0));resultInfo.setUserPhone(row.getField(1));resultInfo.setUserName(row.getField(2));resultInfo.setRegistTime(row.getField(3));resultInfo.setUserlevel(row.getField(4));resultInfo.setAppName(row.getField(5));listResultInfo.add(resultInfo);}}return listResultInfo ;}

生成CSV文件:

   不罗嗦了直接上代码:

//指定路径和编码
CsvWriter writer = CsvUtil.getWriter("e:/testWrite.csv", CharsetUtil.CHARSET_UTF_8);
//按行写出
writer.write(new String[] {"a1", "b1", "c1"}, new String[] {"a2", "b2", "c2"}, new String[] {"a3", "b3", "c3"}
);

效果如下:

更多推荐

fastCSV实现csv文件内容的读取和生成

本文发布于:2024-02-11 15:33:08,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1681759.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文件   内容   fastCSV   csv

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!