简单读取
简单读取指的是,文件不包含特殊字符。
读取方式:按行读取,然后按逗号进行拆分,一般只需要注意中文乱码。
标准读取
标准的 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);
}
}
标签:文件,读取,字符,引号,逗号,csv
From: https://www.cnblogs.com/chenss15060100790/p/18246798