1 8 package org.jutils.csv; 9 10 import java.util.Vector ; 11 import java.io.BufferedReader ; 12 import java.io.EOFException ; 13 import java.io.FileReader ; 14 import java.io.IOException ; 15 import java.io.Reader ; 16 17 35 36 public class CSVReader { 37 45 public CSVReader (Reader r, char separator) { 46 47 if ( r instanceof BufferedReader ) { 48 this.r = (BufferedReader ) r; 49 } else { 50 this.r = new BufferedReader (r); 51 } 52 this.separator = separator; 53 } 55 60 public CSVReader (Reader r) { 61 62 if ( r instanceof BufferedReader ) { 63 this.r = (BufferedReader ) r; 64 } else { 65 this.r = new BufferedReader (r); 66 } 67 this.separator = ','; 68 } 70 private static final boolean debugging = true; 71 72 75 private BufferedReader r; 76 77 81 private char separator; 82 83 86 private static final int EOL = 0; 87 88 91 private static final int ORDINARY = 1; 92 93 96 private static final int QUOTE = 2; 97 98 102 private static final int SEPARATOR = 3; 103 104 107 private static final int WHITESPACE = 4; 108 109 115 private int categorise ( char c ) { 116 switch ( c ) { 117 case ' ': 118 case '\r': 119 case 0xff: 120 return WHITESPACE; 121 case '#': 124 case '\n': 126 return EOL; 127 case '\"': 128 return QUOTE; 129 default: 130 if (c == separator) { 131 132 return SEPARATOR; 133 } else if ( '!' <= c && c <= '~' ) { 134 135 return ORDINARY; 136 } else if ( 0x00 <= c && c <= 0x20 ) { 137 return WHITESPACE; 138 } else if ( Character.isWhitespace(c) ) { 139 return WHITESPACE; 140 } else { 141 return ORDINARY; 142 } 143 } } 146 147 150 private static final int SEEKINGSTART = 0; 151 152 155 private static final int INPLAIN = 1; 156 157 160 private static final int INQUOTED = 2; 161 162 166 private static final int AFTERENDQUOTE = 3; 167 168 171 private static final int SKIPPINGTAIL = 4; 172 173 176 177 182 private String line = null; 183 184 188 private int lineCount = 0; 189 190 public String [] getLine() { 191 Vector lineArray = new Vector (); 192 String token = null; 193 String returnArray [] = null; 194 195 197 try { 198 while (lineArray.size() == 0) { 199 while ( (token = get() ) != null ) { 200 lineArray.add(token); 201 } } } catch (EOFException e) { 204 return null; 205 } catch (IOException e) { 206 } 207 208 returnArray = new String [lineArray.size()]; 209 210 for(int ii=0; ii < lineArray.size(); ii++) { 211 returnArray[ii] = lineArray.elementAt(ii).toString(); 212 } 214 return returnArray; 215 } 216 217 231 private String get() throws EOFException , IOException { 232 StringBuffer field = new StringBuffer (50); 233 234 readLine(); 235 236 int state = SEEKINGSTART; 237 238 239 240 241 for ( int i=0; i<line.length(); i++ ) { 242 char c = line.charAt(i); 243 int category = categorise(c); 244 switch ( state ) { 245 case SEEKINGSTART: { 246 247 switch ( category ) { 248 case WHITESPACE: 249 250 break; 251 case QUOTE: 252 state = INQUOTED; 253 break; 254 case SEPARATOR: 255 256 line = line.substring(i+1); 257 return ""; 258 case EOL: 259 260 line = null; 261 return null; 262 case ORDINARY: 263 field.append(c); 264 state = INPLAIN; 265 break; 266 } 267 break; 268 } case INPLAIN: { 270 271 switch ( category ) { 272 case QUOTE: 273 throw new IOException ("Malformed CSV stream. Missing quote at start of field on line " + lineCount); 274 case SEPARATOR: 275 276 line = line.substring(i+1); 277 return field.toString().trim(); 278 case EOL: 279 line = line.substring(i); 280 return field.toString().trim(); 281 case WHITESPACE: 282 field.append(' '); 283 break; 284 case ORDINARY: 285 field.append(c); 286 break; 287 } 288 break; 289 } case INQUOTED: { 291 292 switch ( category ) { 293 case QUOTE: 294 state = AFTERENDQUOTE; 295 break; 296 case EOL: 297 throw new IOException ("Malformed CSV stream. Missing quote after field on line "+lineCount); 298 case WHITESPACE: 299 field.append(' '); 300 break; 301 case SEPARATOR: 302 case ORDINARY: 303 field.append(c); 304 break; 305 } 306 break; 307 } case AFTERENDQUOTE: { 309 312 switch ( category ) { 313 case QUOTE: 314 field.append(c); 315 state = INQUOTED; 316 break; 317 case SEPARATOR : 318 319 line = line.substring(i+1); 320 return field.toString().trim(); 321 case EOL: 322 line = line.substring(i); 323 return field.toString().trim(); 324 case WHITESPACE: 325 326 state = SKIPPINGTAIL; 327 break; 328 case ORDINARY: 329 throw new IOException ("Malformed CSV stream, missing separator after field on line " + lineCount); 330 } 331 break; 332 } case SKIPPINGTAIL: { 334 335 switch ( category ) { 336 case SEPARATOR : 337 338 line = line.substring(i+1); 339 return field.toString().trim(); 340 case EOL: 341 line = line.substring(i); 342 return field.toString().trim(); 343 case WHITESPACE: 344 345 break; 346 case QUOTE: 347 case ORDINARY: 348 throw new IOException ("Malformed CSV stream, missing separator after field on line " + lineCount); 349 } break; 351 } } } throw new IOException ("Program logic bug. Should not reach here. Processing line " + lineCount); 355 } 357 363 private void readLine() throws EOFException , IOException { 364 if ( line == null ) { 365 line = r.readLine(); 366 if ( line == null ) { 367 368 throw new EOFException (); 369 } else { 370 line += '\n'; 371 lineCount++; 372 } 373 } 374 } 376 377 388 public void skip(int fields) throws EOFException , IOException { 389 if ( fields <= 0 ) { 390 return; 391 } 392 for ( int i=0; i<fields; i++ ) { 393 get(); 395 } 396 } 398 407 public void skipToNextLine() throws EOFException , IOException { 408 if ( line == null ) { 409 readLine(); 410 } 411 line = null; 412 } 414 417 public void close() throws IOException { 418 if ( r != null ) { 419 r.close(); 420 r = null; 421 } 422 } 424 427 private static void testSingleTokens(String [] args) { 428 if ( debugging ) { 429 try { 430 CSVReader csv = new CSVReader(new FileReader (args[0]), ','); 432 try { 433 while ( true ) { 434 System.out.println(csv.get()); 435 } 436 } catch ( EOFException e ) { 437 } 438 csv.close(); 439 } catch ( IOException e ) { 440 e.printStackTrace(); 441 System.out.println(e.getMessage()); 442 } 443 } } 446 449 private static void testLines(String [] args) { 450 int lineCounter = 0; 451 String loadLine[] = null; 452 String DEL = ","; 453 454 if ( debugging ) { 455 try { 456 CSVReader csv = new CSVReader(new FileReader (args[0]), ','); 458 459 while( (loadLine = csv.getLine()) != null) { 460 lineCounter++; 461 StringBuffer logBuffer = new StringBuffer (); 462 String logLine; 463 logBuffer.append(loadLine[0]); for(int i=1; i < loadLine.length; i++) { 466 logBuffer.append(DEL).append(loadLine[i]); 467 } 468 logLine = logBuffer.toString(); 469 logLine.substring(0, logLine.lastIndexOf(DEL)); 470 System.out.println(logLine); 473 } csv.close(); 475 } catch ( IOException e ) { 476 e.printStackTrace(); 477 System.out.println(e.getMessage()); 478 } 479 } } 482 487 static public void main(String [] args) { 488 testLines(args); 490 } } 493 495 | Popular Tags |