1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
| import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List;
/** * CSV内容读取类封装 * 格式约定: * 列分隔符:默认是逗号”,“ * 封闭符:指定源文件中使用的结束字符,默认为双引号。其中包括:双引号、单引号。 * * 1)每条记录占一行; * 2)分隔符 前后的空格会被忽略; * 3)字段中包含有 分隔符,该字段必须用 封闭符 括起来; * 4)字段中包含有换行符,该字段必须用 封闭符 括起来; * 5)字段前后包含有空格,该字段必须用 封闭符 括起来; * 6)字段中的 封闭符 用两个 封闭符 表示; * 7)第一条记录,可以是字段名; * * 分隔符 和 封闭符 是单一字符。 * @author junfeng */ public class CsvReader implements Closeable { char splitChar = ','; char limitChar = '"'; BufferedReader br; File file; Charset charset = StandardCharsets.UTF_8;
/** * CSV解析类构造函数 * @param file 要读取的文件 */ public CsvReader(File file){ this.file = file; }
/** * CSV解析类构造函数 * @param file 要读取的文件 * @param charset 文件编码 */ public CsvReader(File file,Charset charset){ this.file = file; this.charset = charset; }
/** * CSV解析类构造函数 * @param file 要读取的文件 * @param charset 文件编码 * @param splitChar 分隔符 * @param limitChar 限定符 */ public CsvReader(File file,Charset charset,char splitChar,char limitChar){ this.file = file; this.charset = charset; this.splitChar = splitChar; this.limitChar = limitChar; }
/** * 读取一行 CSV 内容,正常返回 CsvLine 对象,读到文件结束,则返回null * @return CsvLine 封装的内容 * @throws IOException 文件读取异常 */ public CsvLine readLine() throws IOException{ if(br==null){ br = new BufferedReader(new InputStreamReader(new FileInputStream(this.file),charset)); } // 标记当前是否位于 限定符内 boolean inLimit = false; List<String> list = new ArrayList<>(); StringBuilder sbItem = new StringBuilder(); // 标记当前项是否由限定符 包括,如果包括 加入项列表时 不会清空前后的空格 boolean itemInLimit = false; int nextChar = -1; while (true){ int c = nextChar; nextChar = -1; if(c==-1){ c = br.read(); } if(inLimit){ if(c==limitChar){ nextChar = br.read(); if(nextChar==limitChar){ sbItem.append((char)c); nextChar = -1; }else{ inLimit = false; } }else{ sbItem.append((char)c); } }else{ if(c==limitChar){ inLimit = true; sbItem = new StringBuilder(); itemInLimit = true; }else if(c==splitChar){ if(itemInLimit){ list.add(sbItem.toString()); }else{ list.add(sbItem.toString().trim()); } itemInLimit = false; sbItem = new StringBuilder(); }else if(c=='\r'){ // 啥也不干 }else if(c=='\n'){ if(sbItem.length()>0){ if(itemInLimit){ list.add(sbItem.toString()); }else{ list.add(sbItem.toString().trim()); } } break; }else{ sbItem.append((char)c); } }
if(c==-1){ if(list.size()==0){ return null; } break; } } return new CsvLine(list); }
@Override public void close() throws IOException { if(br!=null){ br.close(); } }
public static void main(String[] args) throws IOException { CsvReader reader = new CsvReader(new File("c:/tmp/31.csv"),Charset.forName("gbk")); CsvLine line; while ((line=reader.readLine())!=null){ System.out.println(line); } } }
|