对于2的问题的讨论:
如果我们用Excel文件生成CSV文件,其中数据有半角逗号,Excel会怎么处理呢?试一下,可以看到类似如下的数据。 aaa,bbb,ccc,ddd aaa2,bbb2,,ddd2 aaa3,bbb3,ccc3, aaa4,"bb,b4",ccc4,ddd4 bb,b4被用双引号包围了,这样,我们自己在生成CSV文件的时候,可以模仿EXCEL的操作,把所有的数据都用双引号包围。这时候又出现一个问题,如果数据中有双引号,会怎么样?再次尝试一下。这次输入的数据是bb,b"4",结果是: aaa,bbb,ccc,ddd aaa2,bbb2,,ddd2 aaa3,bbb3,ccc3, aaa4,"bb,b""4""",ccc4,ddd4 双引号被用2个双引号替换了。Excel是这么处理的,我们在生成Excel文件的时候可以模仿处理。这样分析数据的时候,就要有一个严格的算法来进行分析。 由于做的这个类是给web开发用的,我们可以考虑用web常用的转意,将"这个字符转换成"来避免这样的冲突,这样处理的好处是分析字符串的时候,处理简单化了。但是这又引发了别的问题,就是如果数据中原来就有"这样的字符,在将"反转义为"的时候,容易把这些原有的字符也转化了。所以&符号也需要转义。 现在将2个方法折衷,即CSV数据以半角逗号分隔,以"包围。数据中的&,"符号进行转义。 这样的处理,将分析数据的算法难度降低,同时也解决了数据中含有半角逗号,引号的问题。
经过以上的分析,我们可以写CSV生成分析文件的类了。 首先,写出简单的转意静态方法。
public static String CSVEncode(String in){ if ( in == null ) return ""; in.replaceAll("&","&"); in.replaceAll("\"","""); return in; } public static String CSVDecode(String in){ if ( in == null ) return ""; in.replaceAll(""","\""); in.replaceAll("&","&"); return in; }
CSV文件生成类:
package com.vogoal.util.csv; import java.io.FileOutputStream; import java.io.IOException; import com.vogoal.util.UtilCla; /** * @author SinNeR * http://bbs.blueidea.com * * CSVCreater */ public class CSVCreater { private FileOutputStream fos = null; private StringBuffer sb = null; private boolean convertFlag = false; public static final String DEL_CHAR = ","; public static final String AV_CHAR = "\""; public CSVCreater(String arg) throws IOException { fos = new FileOutputStream(arg, false); sb = new StringBuffer(); } public void setData(String data) { if (convertFlag) data = UtilCla.CSVEncode(data); sb.append(AV_CHAR); sb.append(data); sb.append(AV_CHAR); sb.append(DEL_CHAR); } public void setConvertFlag(boolean b) { convertFlag = b; } public void writeLine() { if (sb.charAt(sb.length() - 1) == ',') sb.delete(sb.length() - 1, sb.length()); sb.append("\r\n"); } public void writeDataByLine(String[] args) { for (int i = 0; i < args.length; i++) setData(args[i]); writeLine(); } public void close() throws IOException { try { fos.write(sb.toString().getBytes()); } catch (IOException e) { throw e; } finally { fos.close(); } } public static void main(String[] args) { try { CSVCreater csvCre = new CSVCreater("C:\\test.csv"); csvCre.setConvertFlag(true); csvCre.setData("aaa"); csvCre.setData("aa,a"); csvCre.writeLine(); csvCre.setData("aa\"a"); csvCre.setData("aa,a"); csvCre.setData("aa,a"); csvCre.writeLine(); csvCre.setData("aa\"a"); csvCre.setData("aa,\"a"); csvCre.setData("aa,\"a"); csvCre.setData("aa,\"a"); csvCre.setData("aa,\"a"); csvCre.writeLine(); csvCre.close(); } catch (IOException e) { e.printStackTrace(); } } }
CSV文件分析类:
package com.vogoal.util.csv; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import com.vogoal.util.UtilCla; /** * @author SinNeR * http://bbs.blueidea.com * * CSVAnalysis */ public class CSVAnalysis { private InputStreamReader fr = null; private boolean convertFlag = false; private ArrayList dataContainer = new ArrayList(); public static final String DEL_CHAR = ","; public static final String AV_CHAR = "\""; public CSVAnalysis(String f) throws IOException { fr = new InputStreamReader(new FileInputStream(f)); } public void setConvertFlag(boolean b) { convertFlag = b; } public ArrayList analysis() throws IOException { BufferedReader br = new BufferedReader(fr); String rec = null; try { while ((rec = br.readLine()) != null) { ArrayList alLine = analysisLine(rec); dataContainer.add(alLine); } } catch (IOException e) { throw e; } finally { br.close(); } return dataContainer; } private ArrayList analysisLine(String strLine) { System.out.println(strLine); ArrayList al = new ArrayList(); String[] dataArr = strLine.split(AV_CHAR); for (int i = 1; i < dataArr.length; i = i + 2) { if (convertFlag) al.add(UtilCla.CSVDecode(dataArr[i])); else al.add(dataArr[i]); } return al; } public void close() throws IOException { fr.close(); } public static void main(String[] args) { try { CSVAnalysis csvAna = new CSVAnalysis("C:\\test.csv"); csvAna.setConvertFlag(true); ArrayList al = csvAna.analysis(); for (int i = 0; i < al.size(); i++) { ArrayList al1 = (ArrayList) al.get(i); for (int j = 0; j < al1.size(); j++) { System.out.println(al1.get(j)); } } csvAna.close(); } catch (IOException e) { e.printStackTrace(); } } }
出处:蓝色理想
责任编辑:moby
上一页 Jsp常用功能—CSV文件的生成与分析 [1] 下一页 Jsp常用功能—CSV文件的生成与分析 [3]
◎进入论坛网络编程版块参加讨论
|