关于CSV文件的读写问题(特别是有双引号和逗号的情况)
2016-12-16 18:48
1881 查看
一. 对于CSV的读写既可以像读写txt文件似的读写
/*===================读文件=======================*/ InputStreamReader read = new InputStreamReader( new FileInputStream(file),encoding);//考虑到编码格式 BufferedReader bufferedReader = new BufferedReader(read); String lineTxt; while((lineTxt = bufferedReader.readLine()) != null ){ if(!lineTxt.trim().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 = content.get(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" |
"" | """""" |
另外,如果某字段第一个字符是空格,第二个字符是双引号,这种情况不用特殊处理。Project Manager在给我描述算法的时候,也举了一个字段只有一个双引号的例子,但他不小心在双引号前面加了个空格,把问题掩盖过去了。
因此在写CSV文件时,需要先判断是否有逗号和双引号,并做相应处理
boolean quoteFlag = false;//标记是否添加过双引号 //20161214 若发现有逗号 需前后加引号 否则会出现串列的情况 String value = element[i]; if(value.contains("\"")){ //若发现有双引号 需要将字符串中的一个双引号替换为两个 并且需前后加双引号 value = value.replaceAll("\"","\"\""); value = "\"" + value + "\""; quoteFlag = true; } if(value.contains(",") && !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 = str.replaceAll("\"\"","\"");//把两个双引号换成一个双引号 } return str; } String tempValue = ClassUtil.clearStartAndEndQuote(temp[j]);
三. 文本内容的逗号分隔(参考文章)
当大家进行这一操作的时候通常会遇到如下问题。1: 想分割数据 例如:
"123","Jack jona","Computer science" "234","Joen Dan", "Philosophy"
//当遇到这种数据的时候可直接用 逗号进行分割。
String[] strArr = str.trim().split(",",-1);
2: 分割数据如下:
"123", "jack jona", "New York, NY" "234", "Lee Jack", "Fort myers, FL"
//当遇到这种数据的时候可以直接使用
String[] strArr = str.trim().split(",(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)",-1); //双引号内的逗号不分割 双引号外的逗号进行分割
//进行分割。 这种的好处是只对引号外面的逗号进行分割,对引号内的不分割。
//简单的说这种分割得出的结果是
123| jack jona| New York, NY
234| Lee Jack| Fort myers, FL
相关文章推荐
- CSV 文件处理成 String[] ,网银下载的文本中使用逗号分割, 使用双引号标记字段. 使用String split 会出现把引号中的逗号识别的情况 例如 " ,,,, " , "aaa"
- delphi中关于ShellExecute打开文件所在的位置(处理文件名中有逗号,单引号问题)
- 关于标准C文件流读写问题:fopen,fread,fwrite,fclose的一些注意事项
- 关于MySQL中使用LOAD DATA INFILE导入csv文件时的日期格式问题
- 从CSV文件中读取数据,使用逗号','分割问题
- php使用fputcsv()函数csv文件读写数据的方法(解决中文乱码问题)
- 关于C/C++使用stdio读写文件的问题
- 关于ini文件读写的一些问题
- 关于android里的文件创建及读写问题
- 【MFC】:MFC关于文件读写的代码及结构体的错误问题
- 关于c语言文件读写最后一行重复的问题
- 关于android里的文件创建及读写问题
- 关于Excel保存为csv文件时提示“可能含有与CSV(逗号分隔)不兼容的功能”
- 关于android里的文件创建及读写问题
- 关于CSV文件格式中的换行问题
- 导出csv格式,一个单元格内容包含“逗号”,“双引号”问题
- 关于Win7系统中软件安装目录下ini配置文件的读写问题
- Django 读写CSV 文件乱码问题
- 读写csv文件的问题
- 关于properties配置文件读写,追加以及中文乱码问题