最近在项目中遇到一个导入CSV文件的程序数据缺失严重.2.4G的报表600多万行,导入数据库实际只有200多万行,最后终于找到了问题的所在,并解决了.记录Mark一下
前面的一些曲折过程,怀疑多线程来不及处理直接丢弃,就不讲了.
程序中用了while ((data = csvReader.readNext()) != null)循环进行读取.
查看readNext源码,也是通过BufferedReader的readLine进行一行一行的读取,只是在字符串引用和转义进行了处理.CSV程序默认使用DEFAULT_SEPARATOR = ‘,’逗号作为一列与一列的分割符,DEFAULT_QUOTE_CHARACTER = ‘”’双引号作为字符串引用,就是当一列的内容中出现特殊字符如逗号时,怎么区分这个逗号的是列里面的内容还是列之间的分割,例如,一个文件里面某列内容为a,b,c为了区分这个a b c之间的逗号为本来的内容,所以用”a,b,c”这样表示,DEFAULT_ESCAPE_CHARACTER = ‘\’;反斜杠作为转义.
在字符串引用的处理,发现某列数据以双引号开头,但是在这一行没有发现与之对应的双引号,即是说这一行的双引号为奇数个,会读取下一行进行处理,直到找到与之匹配的双引号.例如,我们的报表在151行在Geometry dash后面出现了特殊字符换行符,在xStep后面也出现了换行符

用vim打开,这一行变成了三行,程序会把这三行当成一行处理,这本身没有什么问题.

但是程序中使用反斜杠作为转义,但是csv文件中使用双引号作为转义,这样就会造成\”这样的双引号不做特殊处理,导致双引号不匹配,程序继续读取下一行,造成数据丢失并且数据混乱.
由于CSVReader默认为反斜杠,又不能将转义设置为双引号,这样会和字符串引用的双引号重复,程序处理会混乱,并且程序会抛出异常The separator, quote, and escape characters must be different!,最后重写一个不带转义的CSVReader构造器,重新打个jar包,最后能够读取数据6340034行,解决
附readNext关键代码:
public String[] readNext() throws IOException {

    String[] result = null;do {String nextLine = getNextLine();if (!hasNext) {return result; // should throw if still pending?}String[] r = parser.parseLineMulti(nextLine);if (r.length > 0) {if (result == null) {result = r;} else {String[] t = new String[result.length+r.length];System.arraycopy(result, 0, t, 0, result.length);System.arraycopy(r, 0, t, result.length, r.length);result = t;}}} while (parser.isPending());return result;
}private String[] parseLine(String nextLine, boolean multi) throws IOException {if (!multi && pending != null) {pending = null;}if (nextLine == null) {if (pending != null) {String s = pending;pending = null;return new String[]{s};} else {return null;}}List<String> tokensOnThisLine = new ArrayList<String>();StringBuilder sb = new StringBuilder(INITIAL_READ_SIZE);boolean inQuotes = false;if (pending != null) {sb.append(pending);pending = null;inQuotes = true;}for (int i = 0; i < nextLine.length(); i++) {char c = nextLine.charAt(i);if ( useEscape && c == this.escape) {if (isNextCharacterEscapable(nextLine, inQuotes || inField, i)) {sb.append(nextLine.charAt(i + 1));i++;}} else if (c == quotechar) {if (isNextCharacterEscapedQuote(nextLine, inQuotes || inField, i)) {sb.append(nextLine.charAt(i + 1));i++;} else {//inQuotes = !inQuotes;// the tricky case of an embedded quote in the middle: a,bc"d"ef,gif (!strictQuotes) {if (i > 2 //not on the beginning of the line&& nextLine.charAt(i - 1) != this.separator //not at the beginning of an escape sequence&& nextLine.length() > (i + 1) &&nextLine.charAt(i + 1) != this.separator //not at the   end of an escape sequence) {if (ignoreLeadingWhiteSpace && sb.length() > 0 && isAllWhiteSpace(sb)) {sb.setLength(0);  //discard white space leading up to quote} else {sb.append(c);//continue;}}}inQuotes = !inQuotes;}inField = !inField;} else if (c == separator && !inQuotes) {tokensOnThisLine.add(sb.toString());sb.setLength(0); // start work on next tokeninField = false;} else {if (!strictQuotes || inQuotes) {sb.append(c);inField = true;}}}// line is done - check statusif (inQuotes) {if (multi) {// continuing a quoted section, re-append newlinesb.append("\n");pending = sb.toString();sb = null; // this partial content is not to be added to field list yet} else {throw new IOException("Un-terminated quoted field at end of CSV line");}}if (sb != null) {tokensOnThisLine.add(sb.toString());}return tokensOnThisLine.toArray(new String[tokensOnThisLine.size()]);}

CSVReader读取数据缺失相关推荐

  1. python抓取数据时失败_爬取数据缺失的补坑,Python数据爬取的坑坑洼洼如何铲平...

    渣渣业余选手讲解,关于爬取数据缺失的补坑,一点点关于Python数据爬取的坑坑洼洼如何铲平,个人的一些心得体会,还有结合实例的数据缺失的补全,几点参考,仅供观赏,如有雷同,那肯定是我抄袭的! 在使用P ...

  2. bootstraptable中responsehandle获取数据缺失_Python中的向量化字符串操作

    Python的一个使用优势是它在处理和操作字符串数据方面相对容易. 在此基础上Pandas提供了一套全面的向量化字符串操作(vectorized string operation),这些操作成为处理现 ...

  3. 【MATLAB】 csvwrite数据缺失怎么办

    MATLAB csvwrite数据缺失怎么办 csv文件介绍 csv文件是一种以纯文本形式存储表格数据并使用逗号分割符分割结构的文件格式,其中,逗号表示数据之间的列分割,换行符表示数据之间的行分割. ...

  4. sqoop从musql导入到hive中数据缺失

    sqoop从musql导入到hive中数据缺失 sqoop是大数据架构中常用的数据导入导出组件之一,只要简单的设置一些参数就可以将数据库的数据快速导入数据仓库中. 但在实际使用过程中,常常会碰到一些问 ...

  5. Tensorflow 从bin文件中读取数据并

    Tensorflow 程序读取数据一共有3种方法: 供给数据(feeding):在程序运行的每一步,让Python代码来供给数据 从文件读取数据: 让一个输入管线从文件中读取数据 预加载数据:在ten ...

  6. Linux从mysql中读取数据_linux shell中读写操作mysql数据库

    本文介绍了如何在shell中读写mysql数据库.主要介绍了如何在shell 中连接mysql数据库,如何在shell中创建数据库,创建表,插入csv文件,读取mysql数据库,导出mysql数据库为 ...

  7. 《Clojure数据分析秘笈》——1.6节从JDBC数据库读取数据

    本节书摘来自华章社区<Clojure数据分析秘笈>一书中的第1章,第1.6节从JDBC数据库读取数据,作者(美)Eric Rochester,更多章节内容可以访问云栖社区"华章社 ...

  8. 多线程不重复读取数据_用 PHP 实现多线程编程

    (给PHP开发者加星标,提升PHP技能) 转自:腾讯云(枕边书) cloud.tencent.com/developer/article/1012783 1.前言 前些天帮同事查一个问题,第一次接触到 ...

  9. cdatabase读取excel第一行数据_“蟒蛇”py对Excel的读取——数据操作用它,老板都得重新认识你...

    在python自动化中,经常会遇到对数据文件的操作,比如添加多名员工,但是直接将员工数据写在python文件中,不但工作量大,要是以后再次遇到类似批量数据操作还会写在python文件中吗? 应对这一问 ...

最新文章

  1. JavaScript—— 前端编程语言
  2. 4.12 总结-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  3. FB面经Prepare: Dot Product
  4. css框架和js框架_优雅设计的顶级CSS框架
  5. javascript数组去重方法汇总
  6. PostgreSQL SSL启用与CA证书生成、配置
  7. 一堂如何提高代码质量的培训课 之 领域驱动设计
  8. Linux Swap机制概述
  9. js 图片浏览插件原生
  10. HDFS常用命令总结
  11. iOS——UINavigationController简单实用以及内存警告处理过程
  12. web网页设计实例作业 :美食坊网站设计——美食坊美食购物主题(15页) HTML+CSS+JavaScript
  13. uniapp 本地缓存剩余时间
  14. c语言中invert什么意思_C语言中init 是什么意思?
  15. opencv读取16位色深图片
  16. 对谈Jason Fox:如何导向探索
  17. 魔鬼与牧师动作分离版
  18. 单元测试(三) mockito入门
  19. UST 与美元脱钩,LUNA 暴跌 99.9%
  20. Google Optimization Tools实现加工车间任务规划【Python版】

热门文章

  1. 懒癌患者必备!Medisana让你在按摩椅上旅游
  2. 初入大便( debian)
  3. 恋爱申请书(致蓝儿)
  4. static 静态全局变量和静态局部变量的特性
  5. 基于Python/Tkinter的拼图单机小游戏
  6. SQL新增、修改和删除数据
  7. [RK3288][Android6.0] Audio的音量设置流程小结
  8. Spring 框架面试题总结(待续更新中...)
  9. office2007尾注参考文献后添加致谢的方法
  10. 第21讲:Python字符串格式化的概念以及使用百分号作为占位符对字符串进行格式化