csv - 文件内容读取

简单读取

简单读取指的是,文件不包含特殊字符。

读取方式:按行读取,然后按逗号进行拆分,一般只需要注意中文乱码。

标准读取

标准的 csv 文件,应当有这些特点:

  • csv 文件不是按行读取,而是按字符读取;
  • csv 文件每一行,字段总数并不是固定的;
  • csv 文件的字段,允许包含逗号和引号,这时候字段需要用引号圈起来;
  • csv 文件的一行,不等价于一行记录,如果字段中包含换行符,一行记录就会被拆分成多行。

因此,csv 文件的读取,实际上,不能草率地直接按行读取。

  • 读取一个字段,如果首字符是引号,则说明字段值中,可能包含引号;
  • 引号的转义,是两个引号,读取到两个引号,需要转义成一个引号;
  • 读取到“引号+逗号”,则说明当前字段读取结束;
  • 读取到“引号+换行符”,则说明当前记录读取结束;

其中,读取到单引号,但是没有跟逗号或者引号,则说明文档内容有误,但是无需报错,当成单引号正常读取即可。

推荐方案

要读取标准的 csv 文件,其实算法是非常复杂的,因此需要考虑性能问题;

日常使用的时候,如果明确文件不包含特殊字符,就可以进行简单读取;

因此,设计上,可以分为两套工具:一套专注于提高读取效率;一套专注与读取内容准确。

不推荐自己编写专业读取工具

想要设计专业的工具,使用标准的手段进行读取,不要尝试自己编码,因为短期内根本不可能实现。

推荐选用类库:open-csv,csv-reader 等。


问题分析:

如果只考虑到功能实现,按照前面提到的思路,一个字符一个字符地读取,技术上没啥问题,最终自然是能实现;

但是,编码实现过程中,必定用到 StringBuilder,如果一个字符一个字符地追加,会造成严重的性能浪费;


关键代码如下,如果你已经准备编码,就会发现算法难度极高。

想要优化得好,最终的代码,只会比 BufferedReader 复杂,除非你有很多时间,不然不推荐自己写。

class Test{

    // 最终会用到的应当是一个字符流
    public static Reader reader;
	
	// 考虑到性能,必定会用到缓存,一次读取一大段
    public static char[] buf;

    public static void main(String[] args) throws IOException {
        len = reader.read(buf);
		
		// 这个函数必定被用到	
        new StringBuilder().append(buf, 0, len);
    }
}

posted on 2024-06-13 21:26  疯狂的妞妞  阅读(6)  评论(0编辑  收藏  举报

导航