View Javadoc

1   package au.com.bytecode.opencsv;
2   
3   /**
4    Copyright 2005 Bytecode Pty Ltd.
5   
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9   
10   http://www.apache.org/licenses/LICENSE-2.0
11  
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   See the License for the specific language governing permissions and
16   limitations under the License.
17   */
18  
19  import java.io.BufferedReader;
20  import java.io.Closeable;
21  import java.io.IOException;
22  import java.io.Reader;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  /**
27   * A very simple CSV reader released under a commercial-friendly license.
28   * 
29   * @author Glen Smith
30   * 
31   */
32  public class CSVReader implements Closeable {
33  
34      private BufferedReader br;
35  
36      private boolean hasNext = true;
37  
38      private CSVParser parser;
39      
40      private int skipLines;
41  
42      private boolean linesSkiped;
43  
44      /**
45       * The default line to start reading.
46       */
47      public static final int DEFAULT_SKIP_LINES = 0;
48  
49      /**
50       * Constructs CSVReader using a comma for the separator.
51       * 
52       * @param reader
53       *            the reader to an underlying CSV source.
54       */
55      public CSVReader(Reader reader) {
56          this(reader, CSVParser.DEFAULT_SEPARATOR, CSVParser.DEFAULT_QUOTE_CHARACTER, CSVParser.DEFAULT_ESCAPE_CHARACTER);
57      }
58  
59      /**
60       * Constructs CSVReader with supplied separator.
61       * 
62       * @param reader
63       *            the reader to an underlying CSV source.
64       * @param separator
65       *            the delimiter to use for separating entries.
66       */
67      public CSVReader(Reader reader, char separator) {
68          this(reader, separator, CSVParser.DEFAULT_QUOTE_CHARACTER, CSVParser.DEFAULT_ESCAPE_CHARACTER);
69      }
70  
71      /**
72       * Constructs CSVReader with supplied separator and quote char.
73       * 
74       * @param reader
75       *            the reader to an underlying CSV source.
76       * @param separator
77       *            the delimiter to use for separating entries
78       * @param quotechar
79       *            the character to use for quoted elements
80       */
81      public CSVReader(Reader reader, char separator, char quotechar) {
82          this(reader, separator, quotechar, CSVParser.DEFAULT_ESCAPE_CHARACTER, DEFAULT_SKIP_LINES, CSVParser.DEFAULT_STRICT_QUOTES);
83      }
84  
85      /**
86       * Constructs CSVReader with supplied separator, quote char and quote handling
87       * behavior.
88       *
89       * @param reader
90       *            the reader to an underlying CSV source.
91       * @param separator
92       *            the delimiter to use for separating entries
93       * @param quotechar
94       *            the character to use for quoted elements
95       * @param strictQuotes
96       *            sets if characters outside the quotes are ignored
97       */
98      public CSVReader(Reader reader, char separator, char quotechar, boolean strictQuotes) {
99          this(reader, separator, quotechar, CSVParser.DEFAULT_ESCAPE_CHARACTER, DEFAULT_SKIP_LINES, strictQuotes);
100     }
101 
102    /**
103      * Constructs CSVReader with supplied separator and quote char.
104      *
105      * @param reader
106      *            the reader to an underlying CSV source.
107      * @param separator
108      *            the delimiter to use for separating entries
109      * @param quotechar
110      *            the character to use for quoted elements
111      * @param escape
112      *            the character to use for escaping a separator or quote
113      */
114 
115     public CSVReader(Reader reader, char separator,
116 			char quotechar, char escape) {
117         this(reader, separator, quotechar, escape, DEFAULT_SKIP_LINES, CSVParser.DEFAULT_STRICT_QUOTES);
118 	}
119     
120     /**
121      * Constructs CSVReader with supplied separator and quote char.
122      * 
123      * @param reader
124      *            the reader to an underlying CSV source.
125      * @param separator
126      *            the delimiter to use for separating entries
127      * @param quotechar
128      *            the character to use for quoted elements
129      * @param line
130      *            the line number to skip for start reading 
131      */
132     public CSVReader(Reader reader, char separator, char quotechar, int line) {
133         this(reader, separator, quotechar, CSVParser.DEFAULT_ESCAPE_CHARACTER, line, CSVParser.DEFAULT_STRICT_QUOTES);
134     }
135 
136     /**
137      * Constructs CSVReader with supplied separator and quote char.
138      *
139      * @param reader
140      *            the reader to an underlying CSV source.
141      * @param separator
142      *            the delimiter to use for separating entries
143      * @param quotechar
144      *            the character to use for quoted elements
145      * @param escape
146      *            the character to use for escaping a separator or quote
147      * @param line
148      *            the line number to skip for start reading
149      */
150     public CSVReader(Reader reader, char separator, char quotechar, char escape, int line) {
151         this(reader, separator, quotechar, escape, line, CSVParser.DEFAULT_STRICT_QUOTES);
152     }
153     
154     /**
155      * Constructs CSVReader with supplied separator and quote char.
156      * 
157      * @param reader
158      *            the reader to an underlying CSV source.
159      * @param separator
160      *            the delimiter to use for separating entries
161      * @param quotechar
162      *            the character to use for quoted elements
163      * @param escape
164      *            the character to use for escaping a separator or quote
165      * @param line
166      *            the line number to skip for start reading
167      * @param strictQuotes
168      *            sets if characters outside the quotes are ignored
169      */
170     public CSVReader(Reader reader, char separator, char quotechar, char escape, int line, boolean strictQuotes) {
171         this.br = new BufferedReader(reader);
172         this.parser = new CSVParser(separator, quotechar, escape, strictQuotes);
173         this.skipLines = line;
174     }
175 
176 
177 	/**
178      * Reads the entire file into a List with each element being a String[] of
179      * tokens.
180      * 
181      * @return a List of String[], with each String[] representing a line of the
182      *         file.
183      * 
184      * @throws IOException
185      *             if bad things happen during the read
186      */
187     public List<String[]> readAll() throws IOException {
188 
189         List<String[]> allElements = new ArrayList<String[]>();
190         while (hasNext) {
191             String[] nextLineAsTokens = readNext();
192             if (nextLineAsTokens != null)
193                 allElements.add(nextLineAsTokens);
194         }
195         return allElements;
196 
197     }
198 
199     /**
200      * Reads the next line from the buffer and converts to a string array.
201      * 
202      * @return a string array with each comma-separated element as a separate
203      *         entry.
204      * 
205      * @throws IOException
206      *             if bad things happen during the read
207      */
208     public String[] readNext() throws IOException {
209     	
210     	String[] result = null;
211     	do {
212     		String nextLine = getNextLine();
213     		if (!hasNext) {
214     			return result; // should throw if still pending?
215     		}
216     		String[] r = parser.parseLineMulti(nextLine);
217     		if (r.length > 0) {
218     			if (result == null) {
219     				result = r;
220     			} else {
221     				String[] t = new String[result.length+r.length];
222     				System.arraycopy(result, 0, t, 0, result.length);
223     				System.arraycopy(r, 0, t, result.length, r.length);
224     				result = t;
225     			}
226     		}
227     	} while (parser.isPending());
228     	return result;
229     }
230 
231     /**
232      * Reads the next line from the file.
233      * 
234      * @return the next line from the file without trailing newline
235      * @throws IOException
236      *             if bad things happen during the read
237      */
238     private String getNextLine() throws IOException {
239     	if (!this.linesSkiped) {
240             for (int i = 0; i < skipLines; i++) {
241                 br.readLine();
242             }
243             this.linesSkiped = true;
244         }
245         String nextLine = br.readLine();
246         if (nextLine == null) {
247             hasNext = false;
248         }
249         return hasNext ? nextLine : null;
250     }
251 
252     /**
253      * Closes the underlying reader.
254      * 
255      * @throws IOException if the close fails
256      */
257     public void close() throws IOException{
258     	br.close();
259     }
260     
261 }