Csv文件,逗号分隔的常用数据文件格式,默认可以用Office软件打开。: |* i( H! Y/ d: j
看项目中以前的处理方式是直接用用java IO类库读取Csv文件,实际处理中发现Csv文件本身包含了对各种特殊字符的处理信息。最常见的比如: F7 R; j K3 b) Q; h% h. d
1. 对包含特殊字符的字符串数据首尾加双引号) X1 |1 d, v8 b! x4 J# }! v
2. 对数据中的单个双引号前加单个双引号
4 R! \; X9 `' S, s' K 其它...
n) r/ Y+ I) U 所以用Java IO读到的字符串全是经过处理后的字符串,在某些场景下是不符合预期需求的。比如我需要的是不做任何处理的原始内容。
: h8 \3 a; ]8 W/ ]; L 项目中另一种常见的文件格式Excel用了POI来处理,但是POI不支持Csv格式,于是找到了javacsv。0 i. q" v+ ]+ m6 e3 n
代码很简单:% e5 F8 w- q+ Y* D. Y
Java代码: w7 _6 W1 d- ~4 W C; J
public List importCsv(String file) {
7 `( ]; k$ ?: o! I1 ? List list = new ArrayList(); }. G# X! S0 w1 V8 [
CsvReader reader = null;
5 R& I Q9 Q8 z0 G" m try {8 N4 Q/ c0 O, L! n& h$ `3 X+ z- A
//初始化CsvReader并指定列分隔符和字符编码
6 C; y1 x# Z8 @7 Q6 n reader = new CsvReader(file, ',', Charset.forName("GBK"));+ C4 ~* U. |0 q% M
while (reader.readRecord()) {
( Z7 W( b) M! |$ s //读取每行数据以数组形式返回
1 |# N6 L9 \) g# R% { String[] str = reader.getValues();
5 e# U/ i# T2 A" E! W! x; N: z if (str != null && str.length > 0) {
) y8 e0 i% O/ r7 M* m if (str[0] != null && !"".equals(str[0].trim())) {
9 m7 Z1 c: N9 Q, s' Z( M" N list.add(str);: d9 q' c7 _& I- S) _+ T, q
}5 k4 q* L( d) F9 c8 z' u
}
+ V; H0 V9 @8 j$ S }
3 a$ v* k" F6 ^3 ]. D; X } catch (FileNotFoundException e) {
h1 m& @4 e: c1 _ log.error("Error reading csv file.",e);# k8 B/ E) R3 s4 k) U$ c
} catch (IOException e) {4 m) ]2 Y& j2 d( S
log.error("",e);4 }* ~8 P) |; C$ O, o
}
) A9 X6 D$ c/ ^- D finally{
( z* @; F4 }; S3 }) w if(reader != null)$ |9 ^5 ^" Q! \: {1 s
//关闭CsvReader
, U3 u4 n& {4 n' \0 g reader.close();
0 G+ C* K- e4 c+ p' q }( C2 |" S8 E1 G5 ^) p, E) S2 I
return list;
E4 K" F) a" n. p. g8 ^: N* N }
( a5 Z) t" U# B2 Y; f z. J 以上代码有几个要点:
+ J3 s0 X) T. q, f5 J0 x 1 初始化CsvReader时指定分隔符和字符编码,如果不指定,默认分别为逗号和ISO-8859-1,我用了GBK,具体使用时要看当时的字符编码而定。
! @( ^: t; M! W- G; @$ w7 E 2 读取每行数据,返回字符串数组,数组内的顺序即文件数据列的顺序; ^3 Z9 o% a+ K3 a+ C) q$ Q
3 最后记得关闭CsvReader, ^) M! h# o/ Z `% {, t$ O
是不是很简单,返回的数组格式也正好是我想要的,而且拿到是原始的数据,没有经过特殊字符处理。+ v$ `. n/ c7 [) k! k
有些童鞋质疑特殊字符未经处理,插到数据库会出错,其实大可不必我们手工处理,一些基础组件比如JDBC的preparedstatement已经包含了对特殊字符的处理,我们只要以绑定参数的形式来传送这些包含特殊字符的数据就可以。常用的持久化框架底层也封装了JDBC,自然也对特殊字符做了处理。 |