关于CSV⽂件的读写问题(特别是有双引号和逗号的情况)
⼀. 对于CSV的读写既可以像读写txt⽂件似的读写
/*===================读⽂件=======================*/
InputStreamReader read = new InputStreamReader(
new FileInputStream(file),encoding);//考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt;
while((lineTxt = adLine()) != null ){
if(!im().equals("")) {
String[] temp = lineTxt.split("\t",-1);
txtList.add(temp);
}
}
read.close();
/*==================写⽂件========================*/
File txtFile = new File(filePath);
//追加
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(txtFile, true),encoding));
if(content != null && content.size()>0){
for(Integer i=0 ; i<content.size(); i++){
String[] element = (i);//⼀⾏元素
if(element != null && element.length > 0){
for(Integer j=0; j<element.length; j++){
String temp = element[j];
if(j == element.length - 1){
bw.write(temp + "\n");
}else{
bw.write(temp + separator);
}
}
}
}
也可以⽤java提供的库javacsv和opencsv写,但是注意javacsv不可追加,中⽂OK;opencsv可追加,但是中⽂会乱码。两者可写⼊字段中含有逗号的内容。
⼆. ⽤写txt⽂件的⽅式写csv时,针对内容中的逗号和双引号要做特殊处理():
CSV全称是:Comma Separated Values 或者 Character Separated Values。
尽管第⼀种说法更常见,但我觉得还是第⼆种说法更确切⼀些,因为你可以使⽤其它字符做分隔符。
使⽤逗号做分隔符的CSV⽂件有⼀个好处:你可以直接⽤Excel打开。如果使⽤其它分隔符,⽐如“|”,你必须告诉Excel该⽂件使
⽤“|”作分隔符,Excel才能把它导⼊进来。
前⼏天,project manager告诉我:我们有许多CSV⽂件,都是使⽤“|”做分隔符,⽤Excel打开的时候⽐较⿇烦,⽤户想在Excel中直接打开。这样就需要使⽤“,”做分隔符。但是⽂件中有些字段含有逗号,必须对这些逗号特殊处理,才能保证CSV⽂件在Excel中正确打开。他还给了我⼀个算法:
如果字段中有逗号(,),该字段使⽤双引号(”)括起来;
如果该字段中有双引号,该双引号前要再加⼀个双引号,然后把该字段使⽤双引号括起来。
看完project manager的要求,我真是满头起包啊。在IT业混了⼗⼏年了,竟然不知道这样处理逗号。
举⼏个例⼦:
字段处理前字段处理后
abc,d2"abc,d2"
ab"c,d2"ab""c,d2"
"abc"""abc"
""""""""
如果字段中有两个挨着的双引号,⽐如:aaa”“ccc。这种情况不⽤特殊处理。这是我在写这篇博客的时候才想起来的,赶忙使⽤Excel测试了⼀下。还好,不⽤特殊处理就能正常打开,不然我还得改程序。当然了,如果你把它处理成:”aaa”“”“ccc” Excel也能正常打开。事后总结总结真是有好处啊。
replaceall()另外,如果某字段第⼀个字符是空格,第⼆个字符是双引号,这种情况不⽤特殊处理。Project Manager在给我描述算法的时候,也举了⼀个字段只有⼀个双引号的例⼦,但他不⼩⼼在双引号前⾯加了个空格,把问题掩盖过去了。
因此在写CSV⽂件时,需要先判断是否有逗号和双引号,并做相应处理
boolean quoteFlag = false;//标记是否添加过双引号
//20161214 若发现有逗号需前后加引号否则会出现串列的情况
String value = element[i];
ains("\"")){ //若发现有双引号需要将字符串中的⼀个双引号替换为两个并且需前后加双引号
value = placeAll("\"","\"\"");
value = "\"" + value + "\"";
quoteFlag = true;
}
ains(",") && !quoteFlag){ //若发现有逗号需前后加引号
value = "\"" + value + "\"";
}
if(j == fileHeader.size() - 1){
bw.write(value + "\n");
}else{
bw.write(value + separator);
}
读这样的csv⽂件时,需要做类似的处理:
//去掉字符串前后字符串 for csv输出
public static String clearStartAndEndQuote(String str){
if(str != null && str.length()>=2) {
if(str.indexOf("\"")==0) str = str.substring(1,str.length()); //去掉第⼀个 "
if(str.lastIndexOf("\"")==(str.length()-1)) str = str.substring(0,str.length()-1); //去掉最后⼀个 "
str = placeAll("\"\"","\"");//把两个双引号换成⼀个双引号
}
return str;
}
String tempValue = ClassUtil.clearStartAndEndQuote(temp[j]);
三. ⽂本内容的逗号分隔()
当⼤家进⾏这⼀操作的时候通常会遇到如下问题。
1: 想分割数据 例如:
"123","Jack jona","Computer science"
"234","Joen Dan", "Philosophy"
//当遇到这种数据的时候可直接⽤ 逗号进⾏分割。
String[] strArr = im().split(",",-1);
2: 分割数据如下:
"123", "jack jona", "New York, NY"
"234", "Lee Jack", "Fort myers, FL"
//当遇到这种数据的时候可以直接使⽤
String[] strArr = im().split(",(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)",-1); //双引号内的逗号不分割双引号外的逗号进⾏分割
//进⾏分割。 这种的好处是只对引号外⾯的逗号进⾏分割,对引号内的不分割。
//简单的说这种分割得出的结果是
123| jack jona| New York, NY
234| Lee Jack| Fort myers, FL
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论