View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.csv;
19  
20  import static org.apache.commons.csv.Constants.BACKSLASH;
21  import static org.apache.commons.csv.Constants.COMMA;
22  import static org.apache.commons.csv.Constants.COMMENT;
23  import static org.apache.commons.csv.Constants.EMPTY;
24  import static org.apache.commons.csv.Constants.CR;
25  import static org.apache.commons.csv.Constants.CRLF;
26  import static org.apache.commons.csv.Constants.DOUBLE_QUOTE_CHAR;
27  import static org.apache.commons.csv.Constants.LF;
28  import static org.apache.commons.csv.Constants.PIPE;
29  import static org.apache.commons.csv.Constants.SP;
30  import static org.apache.commons.csv.Constants.TAB;
31  
32  import java.io.File;
33  import java.io.FileOutputStream;
34  import java.io.IOException;
35  import java.io.OutputStreamWriter;
36  import java.io.Reader;
37  import java.io.Serializable;
38  import java.io.StringWriter;
39  import java.nio.charset.Charset;
40  import java.nio.file.Files;
41  import java.nio.file.Path;
42  import java.sql.ResultSet;
43  import java.sql.ResultSetMetaData;
44  import java.sql.SQLException;
45  import java.util.Arrays;
46  import java.util.HashSet;
47  import java.util.Set;
48  
49  /**
50   * Specifies the format of a CSV file and parses input.
51   *
52   * <h2>Using predefined formats</h2>
53   *
54   * <p>
55   * You can use one of the predefined formats:
56   * </p>
57   *
58   * <ul>
59   * <li>{@link #DEFAULT}</li>
60   * <li>{@link #EXCEL}</li>
61   * <li>{@link #INFORMIX_UNLOAD}</li>
62   * <li>{@link #INFORMIX_UNLOAD_CSV}</li>
63   * <li>{@link #MYSQL}</li>
64   * <li>{@link #RFC4180}</li>
65   * <li>{@link #ORACLE}</li>
66   * <li>{@link #POSTGRESQL_CSV}</li>
67   * <li>{@link #POSTGRESQL_TEXT}</li>
68   * <li>{@link #TDF}</li>
69   * </ul>
70   *
71   * <p>
72   * For example:
73   * </p>
74   *
75   * <pre>
76   * CSVParser parser = CSVFormat.EXCEL.parse(reader);
77   * </pre>
78   *
79   * <p>
80   * The {@link CSVParser} provides static methods to parse other input types, for example:
81   * </p>
82   *
83   * <pre>
84   * CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII, CSVFormat.EXCEL);
85   * </pre>
86   *
87   * <h2>Defining formats</h2>
88   *
89   * <p>
90   * You can extend a format by calling the {@code with} methods. For example:
91   * </p>
92   *
93   * <pre>
94   * CSVFormat.EXCEL.withNullString(&quot;N/A&quot;).withIgnoreSurroundingSpaces(true);
95   * </pre>
96   *
97   * <h2>Defining column names</h2>
98   *
99   * <p>
100  * To define the column names you want to use to access records, write:
101  * </p>
102  *
103  * <pre>
104  * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;);
105  * </pre>
106  *
107  * <p>
108  * Calling {@link #withHeader(String...)} let's you use the given names to address values in a {@link CSVRecord}, and
109  * assumes that your CSV source does not contain a first record that also defines column names.
110  *
111  * If it does, then you are overriding this metadata with your names and you should skip the first record by calling
112  * {@link #withSkipHeaderRecord(boolean)} with {@code true}.
113  * </p>
114  *
115  * <h2>Parsing</h2>
116  *
117  * <p>
118  * You can use a format directly to parse a reader. For example, to parse an Excel file with columns header, write:
119  * </p>
120  *
121  * <pre>
122  * Reader in = ...;
123  * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;).parse(in);
124  * </pre>
125  *
126  * <p>
127  * For other input types, like resources, files, and URLs, use the static methods on {@link CSVParser}.
128  * </p>
129  *
130  * <h2>Referencing columns safely</h2>
131  *
132  * <p>
133  * If your source contains a header record, you can simplify your code and safely reference columns, by using
134  * {@link #withHeader(String...)} with no arguments:
135  * </p>
136  *
137  * <pre>
138  * CSVFormat.EXCEL.withHeader();
139  * </pre>
140  *
141  * <p>
142  * This causes the parser to read the first record and use its values as column names.
143  *
144  * Then, call one of the {@link CSVRecord} get method that takes a String column name argument:
145  * </p>
146  *
147  * <pre>
148  * String value = record.get(&quot;Col1&quot;);
149  * </pre>
150  *
151  * <p>
152  * This makes your code impervious to changes in column order in the CSV file.
153  * </p>
154  *
155  * <h2>Notes</h2>
156  *
157  * <p>
158  * This class is immutable.
159  * </p>
160  */
161 public final class CSVFormat implements Serializable {
162 
163     /**
164      * Predefines formats.
165      *
166      * @since 1.2
167      */
168     public enum Predefined {
169 
170         /**
171          * @see CSVFormat#DEFAULT
172          */
173         Default(CSVFormat.DEFAULT),
174 
175         /**
176          * @see CSVFormat#EXCEL
177          */
178         Excel(CSVFormat.EXCEL),
179 
180         /**
181          * @see CSVFormat#INFORMIX_UNLOAD
182          * @since 1.3
183          */
184         InformixUnload(CSVFormat.INFORMIX_UNLOAD),
185 
186         /**
187          * @see CSVFormat#INFORMIX_UNLOAD_CSV
188          * @since 1.3
189          */
190         InformixUnloadCsv(CSVFormat.INFORMIX_UNLOAD_CSV),
191 
192         /**
193          * @see CSVFormat#MYSQL
194          */
195         MySQL(CSVFormat.MYSQL),
196 
197         /**
198          * @see CSVFormat#ORACLE
199          */
200         Oracle(CSVFormat.ORACLE),
201 
202         /**
203          * @see CSVFormat#POSTGRESQL_CSV
204          * @since 1.5
205          */
206         PostgreSQLCsv(CSVFormat.POSTGRESQL_CSV),
207 
208         /**
209          * @see CSVFormat#POSTGRESQL_CSV
210          */
211         PostgreSQLText(CSVFormat.POSTGRESQL_TEXT),
212 
213         /**
214          * @see CSVFormat#RFC4180
215          */
216         RFC4180(CSVFormat.RFC4180),
217 
218         /**
219          * @see CSVFormat#TDF
220          */
221         TDF(CSVFormat.TDF);
222 
223         private final CSVFormat format;
224 
225         Predefined(final CSVFormat format) {
226             this.format = format;
227         }
228 
229         /**
230          * Gets the format.
231          *
232          * @return the format.
233          */
234         public CSVFormat getFormat() {
235             return format;
236         }
237     }
238 
239     /**
240      * Standard Comma Separated Value format, as for {@link #RFC4180} but allowing empty lines.
241      *
242      * <p>
243      * Settings are:
244      * </p>
245      * <ul>
246      * <li>withDelimiter(',')</li>
247      * <li>withQuote('"')</li>
248      * <li>withRecordSeparator("\r\n")</li>
249      * <li>withIgnoreEmptyLines(true)</li>
250      * </ul>
251      *
252      * @see Predefined#Default
253      */
254     public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF,
255             null, null, null, false, false, false, false, false, false);
256 
257     /**
258      * Excel file format (using a comma as the value delimiter). Note that the actual value delimiter used by Excel is
259      * locale dependent, it might be necessary to customize this format to accommodate to your regional settings.
260      *
261      * <p>
262      * For example for parsing or generating a CSV file on a French system the following format will be used:
263      * </p>
264      *
265      * <pre>
266      * CSVFormat fmt = CSVFormat.EXCEL.withDelimiter(';');
267      * </pre>
268      *
269      * <p>
270      * Settings are:
271      * </p>
272      * <ul>
273      * <li>{@link #withDelimiter(char) withDelimiter(',')}</li>
274      * <li>{@link #withQuote(char) withQuote('"')}</li>
275      * <li>{@link #withRecordSeparator(String) withRecordSeparator("\r\n")}</li>
276      * <li>{@link #withIgnoreEmptyLines(boolean) withIgnoreEmptyLines(false)}</li>
277      * <li>{@link #withAllowMissingColumnNames(boolean) withAllowMissingColumnNames(true)}</li>
278      * </ul>
279      * <p>
280      * Note: This is currently like {@link #RFC4180} plus {@link #withAllowMissingColumnNames(boolean)
281      * withAllowMissingColumnNames(true)} and {@link #withIgnoreEmptyLines(boolean) withIgnoreEmptyLines(false)}.
282      * </p>
283      *
284      * @see Predefined#Excel
285      */
286     // @formatter:off
287     public static final CSVFormat EXCEL = DEFAULT
288             .withIgnoreEmptyLines(false)
289             .withAllowMissingColumnNames();
290     // @formatter:on
291 
292     /**
293      * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation.
294      *
295      * <p>
296      * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
297      * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
298      * </p>
299      *
300      * <p>
301      * Settings are:
302      * </p>
303      * <ul>
304      * <li>withDelimiter(',')</li>
305      * <li>withQuote("\"")</li>
306      * <li>withRecordSeparator('\n')</li>
307      * <li>withEscape('\\')</li>
308      * </ul>
309      *
310      * @see Predefined#MySQL
311      * @see <a href=
312      *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
313      *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>;
314      * @since 1.3
315      */
316     // @formatter:off
317     public static final CSVFormat INFORMIX_UNLOAD = DEFAULT
318             .withDelimiter(PIPE)
319             .withEscape(BACKSLASH)
320             .withQuote(DOUBLE_QUOTE_CHAR)
321             .withRecordSeparator(LF);
322     // @formatter:on
323 
324     /**
325      * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation (escaping is disabled.)
326      *
327      * <p>
328      * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
329      * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
330      * </p>
331      *
332      * <p>
333      * Settings are:
334      * </p>
335      * <ul>
336      * <li>withDelimiter(',')</li>
337      * <li>withQuote("\"")</li>
338      * <li>withRecordSeparator('\n')</li>
339      * </ul>
340      *
341      * @see Predefined#MySQL
342      * @see <a href=
343      *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
344      *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>;
345      * @since 1.3
346      */
347     // @formatter:off
348     public static final CSVFormat INFORMIX_UNLOAD_CSV = DEFAULT
349             .withDelimiter(COMMA)
350             .withQuote(DOUBLE_QUOTE_CHAR)
351             .withRecordSeparator(LF);
352     // @formatter:on
353 
354     /**
355      * Default MySQL format used by the {@code SELECT INTO OUTFILE} and {@code LOAD DATA INFILE} operations.
356      *
357      * <p>
358      * This is a tab-delimited format with a LF character as the line separator. Values are not quoted and special
359      * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
360      * </p>
361      *
362      * <p>
363      * Settings are:
364      * </p>
365      * <ul>
366      * <li>withDelimiter('\t')</li>
367      * <li>withQuote(null)</li>
368      * <li>withRecordSeparator('\n')</li>
369      * <li>withIgnoreEmptyLines(false)</li>
370      * <li>withEscape('\\')</li>
371      * <li>withNullString("\\N")</li>
372      * <li>withQuoteMode(QuoteMode.ALL_NON_NULL)</li>
373      * </ul>
374      *
375      * @see Predefined#MySQL
376      * @see <a href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html"> http://dev.mysql.com/doc/refman/5.1/en/load
377      *      -data.html</a>
378      */
379     // @formatter:off
380     public static final CSVFormat MYSQL = DEFAULT
381             .withDelimiter(TAB)
382             .withEscape(BACKSLASH)
383             .withIgnoreEmptyLines(false)
384             .withQuote(null)
385             .withRecordSeparator(LF)
386             .withNullString("\\N")
387             .withQuoteMode(QuoteMode.ALL_NON_NULL);
388     // @formatter:off
389 
390     /**
391      * Default Oracle format used by the SQL*Loader utility.
392      *
393      * <p>
394      * This is a comma-delimited format with the system line separator character as the record separator.Values are
395      * double quoted when needed and special characters are escaped with {@code '"'}. The default NULL string is
396      * {@code ""}. Values are trimmed.
397      * </p>
398      *
399      * <p>
400      * Settings are:
401      * </p>
402      * <ul>
403      * <li>withDelimiter(',') // default is {@code FIELDS TERMINATED BY ','}</li>
404      * <li>withQuote('"')  // default is {@code OPTIONALLY ENCLOSED BY '"'}</li>
405      * <li>withSystemRecordSeparator()</li>
406      * <li>withTrim()</li>
407      * <li>withIgnoreEmptyLines(false)</li>
408      * <li>withEscape('\\')</li>
409      * <li>withNullString("\\N")</li>
410      * <li>withQuoteMode(QuoteMode.MINIMAL)</li>
411      * </ul>
412      *
413      * @see Predefined#Oracle
414      * @see <a href="https://s.apache.org/CGXG">Oracle CSV Format Specification</a>
415      * @since 1.6
416      */
417     // @formatter:off
418     public static final CSVFormat ORACLE = DEFAULT
419             .withDelimiter(COMMA)
420             .withEscape(BACKSLASH)
421             .withIgnoreEmptyLines(false)
422             .withQuote(DOUBLE_QUOTE_CHAR)
423             .withNullString("\\N")
424             .withTrim()
425             .withSystemRecordSeparator()
426             .withQuoteMode(QuoteMode.MINIMAL);
427     // @formatter:off
428 
429     /**
430      * Default PostgreSQL CSV format used by the {@code COPY} operation.
431      *
432      * <p>
433      * This is a comma-delimited format with a LF character as the line separator. Values are double quoted and special
434      * characters are escaped with {@code '"'}. The default NULL string is {@code ""}.
435      * </p>
436      *
437      * <p>
438      * Settings are:
439      * </p>
440      * <ul>
441      * <li>withDelimiter(',')</li>
442      * <li>withQuote('"')</li>
443      * <li>withRecordSeparator('\n')</li>
444      * <li>withIgnoreEmptyLines(false)</li>
445      * <li>withEscape('\\')</li>
446      * <li>withNullString("")</li>
447      * <li>withQuoteMode(QuoteMode.ALL_NON_NULL)</li>
448      * </ul>
449      *
450      * @see Predefined#MySQL
451      * @see <a href="https://www.postgresql.org/docs/current/static/sql-copy.html">PostgreSQL COPY command
452      *          documentation</a>
453      * @since 1.5
454      */
455     // @formatter:off
456     public static final CSVFormat POSTGRESQL_CSV = DEFAULT
457             .withDelimiter(COMMA)
458             .withEscape(DOUBLE_QUOTE_CHAR)
459             .withIgnoreEmptyLines(false)
460             .withQuote(DOUBLE_QUOTE_CHAR)
461             .withRecordSeparator(LF)
462             .withNullString(EMPTY)
463             .withQuoteMode(QuoteMode.ALL_NON_NULL);
464     // @formatter:off
465 
466     /**
467      * Default PostgreSQL text format used by the {@code COPY} operation.
468      *
469      * <p>
470      * This is a tab-delimited format with a LF character as the line separator. Values are double quoted and special
471      * characters are escaped with {@code '"'}. The default NULL string is {@code "\\N"}.
472      * </p>
473      *
474      * <p>
475      * Settings are:
476      * </p>
477      * <ul>
478      * <li>withDelimiter('\t')</li>
479      * <li>withQuote('"')</li>
480      * <li>withRecordSeparator('\n')</li>
481      * <li>withIgnoreEmptyLines(false)</li>
482      * <li>withEscape('\\')</li>
483      * <li>withNullString("\\N")</li>
484      * <li>withQuoteMode(QuoteMode.ALL_NON_NULL)</li>
485      * </ul>
486      *
487      * @see Predefined#MySQL
488      * @see <a href="https://www.postgresql.org/docs/current/static/sql-copy.html">PostgreSQL COPY command
489      *          documentation</a>
490      * @since 1.5
491      */
492     // @formatter:off
493     public static final CSVFormat POSTGRESQL_TEXT = DEFAULT
494             .withDelimiter(TAB)
495             .withEscape(DOUBLE_QUOTE_CHAR)
496             .withIgnoreEmptyLines(false)
497             .withQuote(DOUBLE_QUOTE_CHAR)
498             .withRecordSeparator(LF)
499             .withNullString("\\N")
500             .withQuoteMode(QuoteMode.ALL_NON_NULL);
501     // @formatter:off
502 
503     /**
504      * Comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
505      *
506      * <p>
507      * Settings are:
508      * </p>
509      * <ul>
510      * <li>withDelimiter(',')</li>
511      * <li>withQuote('"')</li>
512      * <li>withRecordSeparator("\r\n")</li>
513      * <li>withIgnoreEmptyLines(false)</li>
514      * </ul>
515      *
516      * @see Predefined#RFC4180
517      */
518     public static final CSVFormat RFC4180 = DEFAULT.withIgnoreEmptyLines(false);
519 
520     private static final long serialVersionUID = 1L;
521 
522     /**
523      * Tab-delimited format.
524      *
525      * <p>
526      * Settings are:
527      * </p>
528      * <ul>
529      * <li>withDelimiter('\t')</li>
530      * <li>withQuote('"')</li>
531      * <li>withRecordSeparator("\r\n")</li>
532      * <li>withIgnoreSurroundingSpaces(true)</li>
533      * </ul>
534      *
535      * @see Predefined#TDF
536      */
537     // @formatter:off
538     public static final CSVFormat TDF = DEFAULT
539             .withDelimiter(TAB)
540             .withIgnoreSurroundingSpaces();
541     // @formatter:on
542 
543     /**
544      * Returns true if the given character is a line break character.
545      *
546      * @param c
547      *            the character to check
548      *
549      * @return true if <code>c</code> is a line break character
550      */
551     private static boolean isLineBreak(final char c) {
552         return c == LF || c == CR;
553     }
554 
555     /**
556      * Returns true if the given character is a line break character.
557      *
558      * @param c
559      *            the character to check, may be null
560      *
561      * @return true if <code>c</code> is a line break character (and not null)
562      */
563     private static boolean isLineBreak(final Character c) {
564         return c != null && isLineBreak(c.charValue());
565     }
566 
567     /**
568      * Creates a new CSV format with the specified delimiter.
569      *
570      * <p>
571      * Use this method if you want to create a CSVFormat from scratch. All fields but the delimiter will be initialized
572      * with null/false.
573      * </p>
574      *
575      * @param delimiter
576      *            the char used for value separation, must not be a line break character
577      * @return a new CSV format.
578      * @throws IllegalArgumentException
579      *             if the delimiter is a line break character
580      *
581      * @see #DEFAULT
582      * @see #RFC4180
583      * @see #MYSQL
584      * @see #EXCEL
585      * @see #TDF
586      */
587     public static CSVFormat newFormat(final char delimiter) {
588         return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false,
589                 false, false, false, false);
590     }
591 
592     /**
593      * Gets one of the predefined formats from {@link CSVFormat.Predefined}.
594      *
595      * @param format
596      *            name
597      * @return one of the predefined formats
598      * @since 1.2
599      */
600     public static CSVFormat valueOf(final String format) {
601         return CSVFormat.Predefined.valueOf(format).getFormat();
602     }
603 
604     private final boolean allowMissingColumnNames;
605 
606     private final Character commentMarker; // null if commenting is disabled
607 
608     private final char delimiter;
609 
610     private final Character escapeCharacter; // null if escaping is disabled
611 
612     private final String[] header; // array of header column names
613 
614     private final String[] headerComments; // array of header comment lines
615 
616     private final boolean ignoreEmptyLines;
617 
618     private final boolean ignoreHeaderCase; // should ignore header names case
619 
620     private final boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
621 
622     private final String nullString; // the string to be used for null values
623 
624     private final Character quoteCharacter; // null if quoting is disabled
625 
626     private final QuoteMode quoteMode;
627 
628     private final String recordSeparator; // for outputs
629 
630     private final boolean skipHeaderRecord;
631 
632     private final boolean trailingDelimiter;
633 
634     private final boolean trim;
635 
636     private final boolean autoFlush;
637 
638     /**
639      * Creates a customized CSV format.
640      *
641      * @param delimiter
642      *            the char used for value separation, must not be a line break character
643      * @param quoteChar
644      *            the Character used as value encapsulation marker, may be {@code null} to disable
645      * @param quoteMode
646      *            the quote mode
647      * @param commentStart
648      *            the Character used for comment identification, may be {@code null} to disable
649      * @param escape
650      *            the Character used to escape special characters in values, may be {@code null} to disable
651      * @param ignoreSurroundingSpaces
652      *            {@code true} when whitespaces enclosing values should be ignored
653      * @param ignoreEmptyLines
654      *            {@code true} when the parser should skip empty lines
655      * @param recordSeparator
656      *            the line separator to use for output
657      * @param nullString
658      *            the line separator to use for output
659      * @param headerComments
660      *            the comments to be printed by the Printer before the actual CSV data
661      * @param header
662      *            the header
663      * @param skipHeaderRecord
664      *            TODO
665      * @param allowMissingColumnNames
666      *            TODO
667      * @param ignoreHeaderCase
668      *            TODO
669      * @param trim
670      *            TODO
671      * @param trailingDelimiter
672      *            TODO
673      * @param autoFlush
674      * @throws IllegalArgumentException
675      *             if the delimiter is a line break character
676      */
677     private CSVFormat(final char delimiter, final Character quoteChar, final QuoteMode quoteMode,
678                       final Character commentStart, final Character escape, final boolean ignoreSurroundingSpaces,
679                       final boolean ignoreEmptyLines, final String recordSeparator, final String nullString,
680                       final Object[] headerComments, final String[] header, final boolean skipHeaderRecord,
681                       final boolean allowMissingColumnNames, final boolean ignoreHeaderCase, final boolean trim,
682                       final boolean trailingDelimiter, final boolean autoFlush) {
683         this.delimiter = delimiter;
684         this.quoteCharacter = quoteChar;
685         this.quoteMode = quoteMode;
686         this.commentMarker = commentStart;
687         this.escapeCharacter = escape;
688         this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
689         this.allowMissingColumnNames = allowMissingColumnNames;
690         this.ignoreEmptyLines = ignoreEmptyLines;
691         this.recordSeparator = recordSeparator;
692         this.nullString = nullString;
693         this.headerComments = toStringArray(headerComments);
694         this.header = header == null ? null : header.clone();
695         this.skipHeaderRecord = skipHeaderRecord;
696         this.ignoreHeaderCase = ignoreHeaderCase;
697         this.trailingDelimiter = trailingDelimiter;
698         this.trim = trim;
699         this.autoFlush = autoFlush;
700         validate();
701     }
702 
703     @Override
704     public boolean equals(final Object obj) {
705         if (this == obj) {
706             return true;
707         }
708         if (obj == null) {
709             return false;
710         }
711         if (getClass() != obj.getClass()) {
712             return false;
713         }
714 
715         final CSVFormat other = (CSVFormat) obj;
716         if (delimiter != other.delimiter) {
717             return false;
718         }
719         if (quoteMode != other.quoteMode) {
720             return false;
721         }
722         if (quoteCharacter == null) {
723             if (other.quoteCharacter != null) {
724                 return false;
725             }
726         } else if (!quoteCharacter.equals(other.quoteCharacter)) {
727             return false;
728         }
729         if (commentMarker == null) {
730             if (other.commentMarker != null) {
731                 return false;
732             }
733         } else if (!commentMarker.equals(other.commentMarker)) {
734             return false;
735         }
736         if (escapeCharacter == null) {
737             if (other.escapeCharacter != null) {
738                 return false;
739             }
740         } else if (!escapeCharacter.equals(other.escapeCharacter)) {
741             return false;
742         }
743         if (nullString == null) {
744             if (other.nullString != null) {
745                 return false;
746             }
747         } else if (!nullString.equals(other.nullString)) {
748             return false;
749         }
750         if (!Arrays.equals(header, other.header)) {
751             return false;
752         }
753         if (ignoreSurroundingSpaces != other.ignoreSurroundingSpaces) {
754             return false;
755         }
756         if (ignoreEmptyLines != other.ignoreEmptyLines) {
757             return false;
758         }
759         if (skipHeaderRecord != other.skipHeaderRecord) {
760             return false;
761         }
762         if (recordSeparator == null) {
763             if (other.recordSeparator != null) {
764                 return false;
765             }
766         } else if (!recordSeparator.equals(other.recordSeparator)) {
767             return false;
768         }
769         return true;
770     }
771 
772     /**
773      * Formats the specified values.
774      *
775      * @param values
776      *            the values to format
777      * @return the formatted values
778      */
779     public String format(final Object... values) {
780         final StringWriter out = new StringWriter();
781         try (final CSVPrinter csvPrinter = new CSVPrinter(out, this)) {
782             csvPrinter.printRecord(values);
783             return out.toString().trim();
784         } catch (final IOException e) {
785             // should not happen because a StringWriter does not do IO.
786             throw new IllegalStateException(e);
787         }
788     }
789 
790     /**
791      * Specifies whether missing column names are allowed when parsing the header line.
792      *
793      * @return {@code true} if missing column names are allowed when parsing the header line, {@code false} to throw an
794      *         {@link IllegalArgumentException}.
795      */
796     public boolean getAllowMissingColumnNames() {
797         return allowMissingColumnNames;
798     }
799 
800     /**
801      * Returns whether to flush on close.
802      *
803      * @return whether to flush on close.
804      * @since 1.6
805      */
806     public boolean getAutoFlush() {
807         return autoFlush;
808     }
809 
810     /**
811      * Returns the character marking the start of a line comment.
812      *
813      * @return the comment start marker, may be {@code null}
814      */
815     public Character getCommentMarker() {
816         return commentMarker;
817     }
818 
819     /**
820      * Returns the character delimiting the values (typically ';', ',' or '\t').
821      *
822      * @return the delimiter character
823      */
824     public char getDelimiter() {
825         return delimiter;
826     }
827 
828     /**
829      * Returns the escape character.
830      *
831      * @return the escape character, may be {@code null}
832      */
833     public Character getEscapeCharacter() {
834         return escapeCharacter;
835     }
836 
837     /**
838      * Returns a copy of the header array.
839      *
840      * @return a copy of the header array; {@code null} if disabled, the empty array if to be read from the file
841      */
842     public String[] getHeader() {
843         return header != null ? header.clone() : null;
844     }
845 
846     /**
847      * Returns a copy of the header comment array.
848      *
849      * @return a copy of the header comment array; {@code null} if disabled.
850      */
851     public String[] getHeaderComments() {
852         return headerComments != null ? headerComments.clone() : null;
853     }
854 
855     /**
856      * Specifies whether empty lines between records are ignored when parsing input.
857      *
858      * @return {@code true} if empty lines between records are ignored, {@code false} if they are turned into empty
859      *         records.
860      */
861     public boolean getIgnoreEmptyLines() {
862         return ignoreEmptyLines;
863     }
864 
865     /**
866      * Specifies whether header names will be accessed ignoring case.
867      *
868      * @return {@code true} if header names cases are ignored, {@code false} if they are case sensitive.
869      * @since 1.3
870      */
871     public boolean getIgnoreHeaderCase() {
872         return ignoreHeaderCase;
873     }
874 
875     /**
876      * Specifies whether spaces around values are ignored when parsing input.
877      *
878      * @return {@code true} if spaces around values are ignored, {@code false} if they are treated as part of the value.
879      */
880     public boolean getIgnoreSurroundingSpaces() {
881         return ignoreSurroundingSpaces;
882     }
883 
884     /**
885      * Gets the String to convert to and from {@code null}.
886      * <ul>
887      * <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
888      * records.</li>
889      * <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
890      * </ul>
891      *
892      * @return the String to convert to and from {@code null}. No substitution occurs if {@code null}
893      */
894     public String getNullString() {
895         return nullString;
896     }
897 
898     /**
899      * Returns the character used to encapsulate values containing special characters.
900      *
901      * @return the quoteChar character, may be {@code null}
902      */
903     public Character getQuoteCharacter() {
904         return quoteCharacter;
905     }
906 
907     /**
908      * Returns the quote policy output fields.
909      *
910      * @return the quote policy
911      */
912     public QuoteMode getQuoteMode() {
913         return quoteMode;
914     }
915 
916     /**
917      * Returns the record separator delimiting output records.
918      *
919      * @return the record separator
920      */
921     public String getRecordSeparator() {
922         return recordSeparator;
923     }
924 
925     /**
926      * Returns whether to skip the header record.
927      *
928      * @return whether to skip the header record.
929      */
930     public boolean getSkipHeaderRecord() {
931         return skipHeaderRecord;
932     }
933 
934     /**
935      * Returns whether to add a trailing delimiter.
936      *
937      * @return whether to add a trailing delimiter.
938      * @since 1.3
939      */
940     public boolean getTrailingDelimiter() {
941         return trailingDelimiter;
942     }
943 
944     /**
945      * Returns whether to trim leading and trailing blanks.
946      *
947      * @return whether to trim leading and trailing blanks.
948      */
949     public boolean getTrim() {
950         return trim;
951     }
952 
953     @Override
954     public int hashCode() {
955         final int prime = 31;
956         int result = 1;
957 
958         result = prime * result + delimiter;
959         result = prime * result + ((quoteMode == null) ? 0 : quoteMode.hashCode());
960         result = prime * result + ((quoteCharacter == null) ? 0 : quoteCharacter.hashCode());
961         result = prime * result + ((commentMarker == null) ? 0 : commentMarker.hashCode());
962         result = prime * result + ((escapeCharacter == null) ? 0 : escapeCharacter.hashCode());
963         result = prime * result + ((nullString == null) ? 0 : nullString.hashCode());
964         result = prime * result + (ignoreSurroundingSpaces ? 1231 : 1237);
965         result = prime * result + (ignoreHeaderCase ? 1231 : 1237);
966         result = prime * result + (ignoreEmptyLines ? 1231 : 1237);
967         result = prime * result + (skipHeaderRecord ? 1231 : 1237);
968         result = prime * result + ((recordSeparator == null) ? 0 : recordSeparator.hashCode());
969         result = prime * result + Arrays.hashCode(header);
970         return result;
971     }
972 
973     /**
974      * Specifies whether comments are supported by this format.
975      *
976      * Note that the comment introducer character is only recognized at the start of a line.
977      *
978      * @return {@code true} is comments are supported, {@code false} otherwise
979      */
980     public boolean isCommentMarkerSet() {
981         return commentMarker != null;
982     }
983 
984     /**
985      * Returns whether escape are being processed.
986      *
987      * @return {@code true} if escapes are processed
988      */
989     public boolean isEscapeCharacterSet() {
990         return escapeCharacter != null;
991     }
992 
993     /**
994      * Returns whether a nullString has been defined.
995      *
996      * @return {@code true} if a nullString is defined
997      */
998     public boolean isNullStringSet() {
999         return nullString != null;
1000     }
1001 
1002     /**
1003      * Returns whether a quoteChar has been defined.
1004      *
1005      * @return {@code true} if a quoteChar is defined
1006      */
1007     public boolean isQuoteCharacterSet() {
1008         return quoteCharacter != null;
1009     }
1010 
1011     /**
1012      * Parses the specified content.
1013      *
1014      * <p>
1015      * See also the various static parse methods on {@link CSVParser}.
1016      * </p>
1017      *
1018      * @param in
1019      *            the input stream
1020      * @return a parser over a stream of {@link CSVRecord}s.
1021      * @throws IOException
1022      *             If an I/O error occurs
1023      */
1024     public CSVParser parse(final Reader in) throws IOException {
1025         return new CSVParser(in, this);
1026     }
1027 
1028     /**
1029      * Prints to the specified output.
1030      *
1031      * <p>
1032      * See also {@link CSVPrinter}.
1033      * </p>
1034      *
1035      * @param out
1036      *            the output.
1037      * @return a printer to an output.
1038      * @throws IOException
1039      *             thrown if the optional header cannot be printed.
1040      */
1041     public CSVPrinter print(final Appendable out) throws IOException {
1042         return new CSVPrinter(out, this);
1043     }
1044 
1045     /**
1046      * Prints to the specified output.
1047      *
1048      * <p>
1049      * See also {@link CSVPrinter}.
1050      * </p>
1051      *
1052      * @param out
1053      *            the output.
1054      * @param charset
1055      *            A charset.
1056      * @return a printer to an output.
1057      * @throws IOException
1058      *             thrown if the optional header cannot be printed.
1059      * @since 1.5
1060      */
1061     @SuppressWarnings("resource")
1062     public CSVPrinter print(final File out, final Charset charset) throws IOException {
1063         // The writer will be closed when close() is called.
1064         return new CSVPrinter(new OutputStreamWriter(new FileOutputStream(out), charset), this);
1065     }
1066 
1067     /**
1068      * Prints the {@code value} as the next value on the line to {@code out}. The value will be escaped or encapsulated
1069      * as needed. Useful when one wants to avoid creating CSVPrinters.
1070      *
1071      * @param value
1072      *            value to output.
1073      * @param out
1074      *            where to print the value.
1075      * @param newRecord
1076      *            if this a new record.
1077      * @throws IOException
1078      *             If an I/O error occurs.
1079      * @since 1.4
1080      */
1081     public void print(final Object value, final Appendable out, final boolean newRecord) throws IOException {
1082         // null values are considered empty
1083         // Only call CharSequence.toString() if you have to, helps GC-free use cases.
1084         CharSequence charSequence;
1085         if (value == null) {
1086             // https://issues.apache.org/jira/browse/CSV-203
1087             if (null == nullString) {
1088                 charSequence = EMPTY;
1089             } else {
1090                 if (QuoteMode.ALL == quoteMode) {
1091                     charSequence = quoteCharacter + nullString + quoteCharacter;
1092                 } else {
1093                     charSequence = nullString;
1094                 }
1095             }
1096         } else {
1097             charSequence = value instanceof CharSequence ? (CharSequence) value : value.toString();
1098         }
1099         charSequence = getTrim() ? trim(charSequence) : charSequence;
1100         this.print(value, charSequence, 0, charSequence.length(), out, newRecord);
1101     }
1102 
1103     private void print(final Object object, final CharSequence value, final int offset, final int len,
1104             final Appendable out, final boolean newRecord) throws IOException {
1105         if (!newRecord) {
1106             out.append(getDelimiter());
1107         }
1108         if (object == null) {
1109             out.append(value);
1110         } else if (isQuoteCharacterSet()) {
1111             // the original object is needed so can check for Number
1112             printAndQuote(object, value, offset, len, out, newRecord);
1113         } else if (isEscapeCharacterSet()) {
1114             printAndEscape(value, offset, len, out);
1115         } else {
1116             out.append(value, offset, offset + len);
1117         }
1118     }
1119 
1120     /**
1121      * Prints to the specified output.
1122      *
1123      * <p>
1124      * See also {@link CSVPrinter}.
1125      * </p>
1126      *
1127      * @param out
1128      *            the output.
1129      * @param charset
1130      *            A charset.
1131      * @return a printer to an output.
1132      * @throws IOException
1133      *             thrown if the optional header cannot be printed.
1134      * @since 1.5
1135      */
1136     public CSVPrinter print(final Path out, final Charset charset) throws IOException {
1137         return print(Files.newBufferedWriter(out, charset));
1138     }
1139 
1140     /*
1141      * Note: must only be called if escaping is enabled, otherwise will generate NPE
1142      */
1143     private void printAndEscape(final CharSequence value, final int offset, final int len, final Appendable out)
1144             throws IOException {
1145         int start = offset;
1146         int pos = offset;
1147         final int end = offset + len;
1148 
1149         final char delim = getDelimiter();
1150         final char escape = getEscapeCharacter().charValue();
1151 
1152         while (pos < end) {
1153             char c = value.charAt(pos);
1154             if (c == CR || c == LF || c == delim || c == escape) {
1155                 // write out segment up until this char
1156                 if (pos > start) {
1157                     out.append(value, start, pos);
1158                 }
1159                 if (c == LF) {
1160                     c = 'n';
1161                 } else if (c == CR) {
1162                     c = 'r';
1163                 }
1164 
1165                 out.append(escape);
1166                 out.append(c);
1167 
1168                 start = pos + 1; // start on the current char after this one
1169             }
1170 
1171             pos++;
1172         }
1173 
1174         // write last segment
1175         if (pos > start) {
1176             out.append(value, start, pos);
1177         }
1178     }
1179 
1180     /*
1181      * Note: must only be called if quoting is enabled, otherwise will generate NPE
1182      */
1183     // the original object is needed so can check for Number
1184     private void printAndQuote(final Object object, final CharSequence value, final int offset, final int len,
1185             final Appendable out, final boolean newRecord) throws IOException {
1186         boolean quote = false;
1187         int start = offset;
1188         int pos = offset;
1189         final int end = offset + len;
1190 
1191         final char delimChar = getDelimiter();
1192         final char quoteChar = getQuoteCharacter().charValue();
1193 
1194         QuoteMode quoteModePolicy = getQuoteMode();
1195         if (quoteModePolicy == null) {
1196             quoteModePolicy = QuoteMode.MINIMAL;
1197         }
1198         switch (quoteModePolicy) {
1199         case ALL:
1200         case ALL_NON_NULL:
1201             quote = true;
1202             break;
1203         case NON_NUMERIC:
1204             quote = !(object instanceof Number);
1205             break;
1206         case NONE:
1207             // Use the existing escaping code
1208             printAndEscape(value, offset, len, out);
1209             return;
1210         case MINIMAL:
1211             if (len <= 0) {
1212                 // always quote an empty token that is the first
1213                 // on the line, as it may be the only thing on the
1214                 // line. If it were not quoted in that case,
1215                 // an empty line has no tokens.
1216                 if (newRecord) {
1217                     quote = true;
1218                 }
1219             } else {
1220                 char c = value.charAt(pos);
1221 
1222                 if (c <= COMMENT) {
1223                     // Some other chars at the start of a value caused the parser to fail, so for now
1224                     // encapsulate if we start in anything less than '#'. We are being conservative
1225                     // by including the default comment char too.
1226                     quote = true;
1227                 } else {
1228                     while (pos < end) {
1229                         c = value.charAt(pos);
1230                         if (c == LF || c == CR || c == quoteChar || c == delimChar) {
1231                             quote = true;
1232                             break;
1233                         }
1234                         pos++;
1235                     }
1236 
1237                     if (!quote) {
1238                         pos = end - 1;
1239                         c = value.charAt(pos);
1240                         // Some other chars at the end caused the parser to fail, so for now
1241                         // encapsulate if we end in anything less than ' '
1242                         if (c <= SP) {
1243                             quote = true;
1244                         }
1245                     }
1246                 }
1247             }
1248 
1249             if (!quote) {
1250                 // no encapsulation needed - write out the original value
1251                 out.append(value, start, end);
1252                 return;
1253             }
1254             break;
1255         default:
1256             throw new IllegalStateException("Unexpected Quote value: " + quoteModePolicy);
1257         }
1258 
1259         if (!quote) {
1260             // no encapsulation needed - write out the original value
1261             out.append(value, start, end);
1262             return;
1263         }
1264 
1265         // we hit something that needed encapsulation
1266         out.append(quoteChar);
1267 
1268         // Pick up where we left off: pos should be positioned on the first character that caused
1269         // the need for encapsulation.
1270         while (pos < end) {
1271             final char c = value.charAt(pos);
1272             if (c == quoteChar) {
1273                 // write out the chunk up until this point
1274 
1275                 // add 1 to the length to write out the encapsulator also
1276                 out.append(value, start, pos + 1);
1277                 // put the next starting position on the encapsulator so we will
1278                 // write it out again with the next string (effectively doubling it)
1279                 start = pos;
1280             }
1281             pos++;
1282         }
1283 
1284         // write the last segment
1285         out.append(value, start, pos);
1286         out.append(quoteChar);
1287     }
1288 
1289     /**
1290      * Prints to the {@link System#out}.
1291      *
1292      * <p>
1293      * See also {@link CSVPrinter}.
1294      * </p>
1295      *
1296      * @return a printer to {@link System#out}.
1297      * @throws IOException
1298      *             thrown if the optional header cannot be printed.
1299      * @since 1.5
1300      */
1301     public CSVPrinter printer() throws IOException {
1302         return new CSVPrinter(System.out, this);
1303     }
1304 
1305     /**
1306      * Outputs the trailing delimiter (if set) followed by the record separator (if set).
1307      *
1308      * @param out
1309      *            where to write
1310      * @throws IOException
1311      *             If an I/O error occurs
1312      * @since 1.4
1313      */
1314     public void println(final Appendable out) throws IOException {
1315         if (getTrailingDelimiter()) {
1316             out.append(getDelimiter());
1317         }
1318         if (recordSeparator != null) {
1319             out.append(recordSeparator);
1320         }
1321     }
1322 
1323     /**
1324      * Prints the given {@code values} to {@code out} as a single record of delimiter separated values followed by the
1325      * record separator.
1326      *
1327      * <p>
1328      * The values will be quoted if needed. Quotes and new-line characters will be escaped. This method adds the record
1329      * separator to the output after printing the record, so there is no need to call {@link #println(Appendable)}.
1330      * </p>
1331      *
1332      * @param out
1333      *            where to write.
1334      * @param values
1335      *            values to output.
1336      * @throws IOException
1337      *             If an I/O error occurs.
1338      * @since 1.4
1339      */
1340     public void printRecord(final Appendable out, final Object... values) throws IOException {
1341         for (int i = 0; i < values.length; i++) {
1342             print(values[i], out, i == 0);
1343         }
1344         println(out);
1345     }
1346 
1347     @Override
1348     public String toString() {
1349         final StringBuilder sb = new StringBuilder();
1350         sb.append("Delimiter=<").append(delimiter).append('>');
1351         if (isEscapeCharacterSet()) {
1352             sb.append(' ');
1353             sb.append("Escape=<").append(escapeCharacter).append('>');
1354         }
1355         if (isQuoteCharacterSet()) {
1356             sb.append(' ');
1357             sb.append("QuoteChar=<").append(quoteCharacter).append('>');
1358         }
1359         if (isCommentMarkerSet()) {
1360             sb.append(' ');
1361             sb.append("CommentStart=<").append(commentMarker).append('>');
1362         }
1363         if (isNullStringSet()) {
1364             sb.append(' ');
1365             sb.append("NullString=<").append(nullString).append('>');
1366         }
1367         if (recordSeparator != null) {
1368             sb.append(' ');
1369             sb.append("RecordSeparator=<").append(recordSeparator).append('>');
1370         }
1371         if (getIgnoreEmptyLines()) {
1372             sb.append(" EmptyLines:ignored");
1373         }
1374         if (getIgnoreSurroundingSpaces()) {
1375             sb.append(" SurroundingSpaces:ignored");
1376         }
1377         if (getIgnoreHeaderCase()) {
1378             sb.append(" IgnoreHeaderCase:ignored");
1379         }
1380         sb.append(" SkipHeaderRecord:").append(skipHeaderRecord);
1381         if (headerComments != null) {
1382             sb.append(' ');
1383             sb.append("HeaderComments:").append(Arrays.toString(headerComments));
1384         }
1385         if (header != null) {
1386             sb.append(' ');
1387             sb.append("Header:").append(Arrays.toString(header));
1388         }
1389         return sb.toString();
1390     }
1391 
1392     private String[] toStringArray(final Object[] values) {
1393         if (values == null) {
1394             return null;
1395         }
1396         final String[] strings = new String[values.length];
1397         for (int i = 0; i < values.length; i++) {
1398             final Object value = values[i];
1399             strings[i] = value == null ? null : value.toString();
1400         }
1401         return strings;
1402     }
1403 
1404     private CharSequence trim(final CharSequence charSequence) {
1405         if (charSequence instanceof String) {
1406             return ((String) charSequence).trim();
1407         }
1408         final int count = charSequence.length();
1409         int len = count;
1410         int pos = 0;
1411 
1412         while (pos < len && charSequence.charAt(pos) <= SP) {
1413             pos++;
1414         }
1415         while (pos < len && charSequence.charAt(len - 1) <= SP) {
1416             len--;
1417         }
1418         return pos > 0 || len < count ? charSequence.subSequence(pos, len) : charSequence;
1419     }
1420 
1421     /**
1422      * Verifies the consistency of the parameters and throws an IllegalArgumentException if necessary.
1423      *
1424      * @throws IllegalArgumentException
1425      */
1426     private void validate() throws IllegalArgumentException {
1427         if (isLineBreak(delimiter)) {
1428             throw new IllegalArgumentException("The delimiter cannot be a line break");
1429         }
1430 
1431         if (quoteCharacter != null && delimiter == quoteCharacter.charValue()) {
1432             throw new IllegalArgumentException(
1433                     "The quoteChar character and the delimiter cannot be the same ('" + quoteCharacter + "')");
1434         }
1435 
1436         if (escapeCharacter != null && delimiter == escapeCharacter.charValue()) {
1437             throw new IllegalArgumentException(
1438                     "The escape character and the delimiter cannot be the same ('" + escapeCharacter + "')");
1439         }
1440 
1441         if (commentMarker != null && delimiter == commentMarker.charValue()) {
1442             throw new IllegalArgumentException(
1443                     "The comment start character and the delimiter cannot be the same ('" + commentMarker + "')");
1444         }
1445 
1446         if (quoteCharacter != null && quoteCharacter.equals(commentMarker)) {
1447             throw new IllegalArgumentException(
1448                     "The comment start character and the quoteChar cannot be the same ('" + commentMarker + "')");
1449         }
1450 
1451         if (escapeCharacter != null && escapeCharacter.equals(commentMarker)) {
1452             throw new IllegalArgumentException(
1453                     "The comment start and the escape character cannot be the same ('" + commentMarker + "')");
1454         }
1455 
1456         if (escapeCharacter == null && quoteMode == QuoteMode.NONE) {
1457             throw new IllegalArgumentException("No quotes mode set but no escape character is set");
1458         }
1459 
1460         // validate header
1461         if (header != null) {
1462             final Set<String> dupCheck = new HashSet<>();
1463             for (final String hdr : header) {
1464                 if (!dupCheck.add(hdr)) {
1465                     throw new IllegalArgumentException(
1466                             "The header contains a duplicate entry: '" + hdr + "' in " + Arrays.toString(header));
1467                 }
1468             }
1469         }
1470     }
1471 
1472     /**
1473      * Returns a new {@code CSVFormat} with the missing column names behavior of the format set to {@code true}
1474      *
1475      * @return A new CSVFormat that is equal to this but with the specified missing column names behavior.
1476      * @see #withAllowMissingColumnNames(boolean)
1477      * @since 1.1
1478      */
1479     public CSVFormat withAllowMissingColumnNames() {
1480         return this.withAllowMissingColumnNames(true);
1481     }
1482 
1483     /**
1484      * Returns a new {@code CSVFormat} with the missing column names behavior of the format set to the given value.
1485      *
1486      * @param allowMissingColumnNames
1487      *            the missing column names behavior, {@code true} to allow missing column names in the header line,
1488      *            {@code false} to cause an {@link IllegalArgumentException} to be thrown.
1489      * @return A new CSVFormat that is equal to this but with the specified missing column names behavior.
1490      */
1491     public CSVFormat withAllowMissingColumnNames(final boolean allowMissingColumnNames) {
1492         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1493                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1494                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1495     }
1496 
1497     /**
1498      * Returns a new {@code CSVFormat} with whether to flush on close.
1499      *
1500      * @param autoFlush
1501      *            whether to flush on close.
1502      *
1503      * @return A new CSVFormat that is equal to this but with the specified autoFlush setting.
1504      * @since 1.6
1505      */
1506     public CSVFormat withAutoFlush(final boolean autoFlush) {
1507         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1508             ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1509             skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1510     }
1511 
1512     /**
1513      * Returns a new {@code CSVFormat} with the comment start marker of the format set to the specified character.
1514      *
1515      * Note that the comment start character is only recognized at the start of a line.
1516      *
1517      * @param commentMarker
1518      *            the comment start marker
1519      * @return A new CSVFormat that is equal to this one but with the specified character as the comment start marker
1520      * @throws IllegalArgumentException
1521      *             thrown if the specified character is a line break
1522      */
1523     public CSVFormat withCommentMarker(final char commentMarker) {
1524         return withCommentMarker(Character.valueOf(commentMarker));
1525     }
1526 
1527     /**
1528      * Returns a new {@code CSVFormat} with the comment start marker of the format set to the specified character.
1529      *
1530      * Note that the comment start character is only recognized at the start of a line.
1531      *
1532      * @param commentMarker
1533      *            the comment start marker, use {@code null} to disable
1534      * @return A new CSVFormat that is equal to this one but with the specified character as the comment start marker
1535      * @throws IllegalArgumentException
1536      *             thrown if the specified character is a line break
1537      */
1538     public CSVFormat withCommentMarker(final Character commentMarker) {
1539         if (isLineBreak(commentMarker)) {
1540             throw new IllegalArgumentException("The comment start marker character cannot be a line break");
1541         }
1542         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1543                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1544                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1545     }
1546 
1547     /**
1548      * Returns a new {@code CSVFormat} with the delimiter of the format set to the specified character.
1549      *
1550      * @param delimiter
1551      *            the delimiter character
1552      * @return A new CSVFormat that is equal to this with the specified character as delimiter
1553      * @throws IllegalArgumentException
1554      *             thrown if the specified character is a line break
1555      */
1556     public CSVFormat withDelimiter(final char delimiter) {
1557         if (isLineBreak(delimiter)) {
1558             throw new IllegalArgumentException("The delimiter cannot be a line break");
1559         }
1560         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1561                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1562                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1563     }
1564 
1565     /**
1566      * Returns a new {@code CSVFormat} with the escape character of the format set to the specified character.
1567      *
1568      * @param escape
1569      *            the escape character
1570      * @return A new CSVFormat that is equal to his but with the specified character as the escape character
1571      * @throws IllegalArgumentException
1572      *             thrown if the specified character is a line break
1573      */
1574     public CSVFormat withEscape(final char escape) {
1575         return withEscape(Character.valueOf(escape));
1576     }
1577 
1578     /**
1579      * Returns a new {@code CSVFormat} with the escape character of the format set to the specified character.
1580      *
1581      * @param escape
1582      *            the escape character, use {@code null} to disable
1583      * @return A new CSVFormat that is equal to this but with the specified character as the escape character
1584      * @throws IllegalArgumentException
1585      *             thrown if the specified character is a line break
1586      */
1587     public CSVFormat withEscape(final Character escape) {
1588         if (isLineBreak(escape)) {
1589             throw new IllegalArgumentException("The escape character cannot be a line break");
1590         }
1591         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escape, ignoreSurroundingSpaces,
1592                 ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
1593                 allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1594     }
1595 
1596     /**
1597      * Returns a new {@code CSVFormat} using the first record as header.
1598      *
1599      * <p>
1600      * Calling this method is equivalent to calling:
1601      * </p>
1602      *
1603      * <pre>
1604      * CSVFormat format = aFormat.withHeader().withSkipHeaderRecord();
1605      * </pre>
1606      *
1607      * @return A new CSVFormat that is equal to this but using the first record as header.
1608      * @see #withSkipHeaderRecord(boolean)
1609      * @see #withHeader(String...)
1610      * @since 1.3
1611      */
1612     public CSVFormat withFirstRecordAsHeader() {
1613         return withHeader().withSkipHeaderRecord();
1614     }
1615 
1616     /**
1617      * Returns a new {@code CSVFormat} with the header of the format defined by the enum class.
1618      *
1619      * <p>
1620      * Example:
1621      * </p>
1622      * <pre>
1623      * public enum Header {
1624      *     Name, Email, Phone
1625      * }
1626      *
1627      * CSVFormat format = aformat.withHeader(Header.class);
1628      * </pre>
1629      * <p>
1630      * The header is also used by the {@link CSVPrinter}.
1631      * </p>
1632      *
1633      * @param headerEnum
1634      *            the enum defining the header, {@code null} if disabled, empty if parsed automatically, user specified
1635      *            otherwise.
1636      *
1637      * @return A new CSVFormat that is equal to this but with the specified header
1638      * @see #withHeader(String...)
1639      * @see #withSkipHeaderRecord(boolean)
1640      * @since 1.3
1641      */
1642     public CSVFormat withHeader(final Class<? extends Enum<?>> headerEnum) {
1643         String[] header = null;
1644         if (headerEnum != null) {
1645             final Enum<?>[] enumValues = headerEnum.getEnumConstants();
1646             header = new String[enumValues.length];
1647             for (int i = 0; i < enumValues.length; i++) {
1648                 header[i] = enumValues[i].name();
1649             }
1650         }
1651         return withHeader(header);
1652     }
1653 
1654     /**
1655      * Returns a new {@code CSVFormat} with the header of the format set from the result set metadata. The header can
1656      * either be parsed automatically from the input file with:
1657      *
1658      * <pre>
1659      * CSVFormat format = aformat.withHeader();
1660      * </pre>
1661      *
1662      * or specified manually with:
1663      *
1664      * <pre>
1665      * CSVFormat format = aformat.withHeader(resultSet);
1666      * </pre>
1667      * <p>
1668      * The header is also used by the {@link CSVPrinter}.
1669      * </p>
1670      *
1671      * @param resultSet
1672      *            the resultSet for the header, {@code null} if disabled, empty if parsed automatically, user specified
1673      *            otherwise.
1674      *
1675      * @return A new CSVFormat that is equal to this but with the specified header
1676      * @throws SQLException
1677      *             SQLException if a database access error occurs or this method is called on a closed result set.
1678      * @since 1.1
1679      */
1680     public CSVFormat withHeader(final ResultSet resultSet) throws SQLException {
1681         return withHeader(resultSet != null ? resultSet.getMetaData() : null);
1682     }
1683 
1684     /**
1685      * Returns a new {@code CSVFormat} with the header of the format set from the result set metadata. The header can
1686      * either be parsed automatically from the input file with:
1687      *
1688      * <pre>
1689      * CSVFormat format = aformat.withHeader();
1690      * </pre>
1691      *
1692      * or specified manually with:
1693      *
1694      * <pre>
1695      * CSVFormat format = aformat.withHeader(metaData);
1696      * </pre>
1697      * <p>
1698      * The header is also used by the {@link CSVPrinter}.
1699      * </p>
1700      *
1701      * @param metaData
1702      *            the metaData for the header, {@code null} if disabled, empty if parsed automatically, user specified
1703      *            otherwise.
1704      *
1705      * @return A new CSVFormat that is equal to this but with the specified header
1706      * @throws SQLException
1707      *             SQLException if a database access error occurs or this method is called on a closed result set.
1708      * @since 1.1
1709      */
1710     public CSVFormat withHeader(final ResultSetMetaData metaData) throws SQLException {
1711         String[] labels = null;
1712         if (metaData != null) {
1713             final int columnCount = metaData.getColumnCount();
1714             labels = new String[columnCount];
1715             for (int i = 0; i < columnCount; i++) {
1716                 labels[i] = metaData.getColumnLabel(i + 1);
1717             }
1718         }
1719         return withHeader(labels);
1720     }
1721 
1722     /**
1723      * Returns a new {@code CSVFormat} with the header of the format set to the given values. The header can either be
1724      * parsed automatically from the input file with:
1725      *
1726      * <pre>
1727      * CSVFormat format = aformat.withHeader();
1728      * </pre>
1729      *
1730      * or specified manually with:
1731      *
1732      * <pre>
1733      * CSVFormat format = aformat.withHeader(&quot;name&quot;, &quot;email&quot;, &quot;phone&quot;);
1734      * </pre>
1735      * <p>
1736      * The header is also used by the {@link CSVPrinter}.
1737      * </p>
1738      *
1739      * @param header
1740      *            the header, {@code null} if disabled, empty if parsed automatically, user specified otherwise.
1741      *
1742      * @return A new CSVFormat that is equal to this but with the specified header
1743      * @see #withSkipHeaderRecord(boolean)
1744      */
1745     public CSVFormat withHeader(final String... header) {
1746         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1747                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1748                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1749     }
1750 
1751     /**
1752      * Returns a new {@code CSVFormat} with the header comments of the format set to the given values. The comments will
1753      * be printed first, before the headers. This setting is ignored by the parser.
1754      *
1755      * <pre>
1756      * CSVFormat format = aformat.withHeaderComments(&quot;Generated by Apache Commons CSV 1.1.&quot;, new Date());
1757      * </pre>
1758      *
1759      * @param headerComments
1760      *            the headerComments which will be printed by the Printer before the actual CSV data.
1761      *
1762      * @return A new CSVFormat that is equal to this but with the specified header
1763      * @see #withSkipHeaderRecord(boolean)
1764      * @since 1.1
1765      */
1766     public CSVFormat withHeaderComments(final Object... headerComments) {
1767         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1768                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1769                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1770     }
1771 
1772     /**
1773      * Returns a new {@code CSVFormat} with the empty line skipping behavior of the format set to {@code true}.
1774      *
1775      * @return A new CSVFormat that is equal to this but with the specified empty line skipping behavior.
1776      * @since {@link #withIgnoreEmptyLines(boolean)}
1777      * @since 1.1
1778      */
1779     public CSVFormat withIgnoreEmptyLines() {
1780         return this.withIgnoreEmptyLines(true);
1781     }
1782 
1783     /**
1784      * Returns a new {@code CSVFormat} with the empty line skipping behavior of the format set to the given value.
1785      *
1786      * @param ignoreEmptyLines
1787      *            the empty line skipping behavior, {@code true} to ignore the empty lines between the records,
1788      *            {@code false} to translate empty lines to empty records.
1789      * @return A new CSVFormat that is equal to this but with the specified empty line skipping behavior.
1790      */
1791     public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines) {
1792         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1793                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1794                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1795     }
1796 
1797     /**
1798      * Returns a new {@code CSVFormat} with the header ignore case behavior set to {@code true}.
1799      *
1800      * @return A new CSVFormat that will ignore case header name.
1801      * @see #withIgnoreHeaderCase(boolean)
1802      * @since 1.3
1803      */
1804     public CSVFormat withIgnoreHeaderCase() {
1805         return this.withIgnoreHeaderCase(true);
1806     }
1807 
1808     /**
1809      * Returns a new {@code CSVFormat} with whether header names should be accessed ignoring case.
1810      *
1811      * @param ignoreHeaderCase
1812      *            the case mapping behavior, {@code true} to access name/values, {@code false} to leave the mapping as
1813      *            is.
1814      * @return A new CSVFormat that will ignore case header name if specified as {@code true}
1815      * @since 1.3
1816      */
1817     public CSVFormat withIgnoreHeaderCase(final boolean ignoreHeaderCase) {
1818         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1819                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1820                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1821     }
1822 
1823     /**
1824      * Returns a new {@code CSVFormat} with the trimming behavior of the format set to {@code true}.
1825      *
1826      * @return A new CSVFormat that is equal to this but with the specified trimming behavior.
1827      * @see #withIgnoreSurroundingSpaces(boolean)
1828      * @since 1.1
1829      */
1830     public CSVFormat withIgnoreSurroundingSpaces() {
1831         return this.withIgnoreSurroundingSpaces(true);
1832     }
1833 
1834     /**
1835      * Returns a new {@code CSVFormat} with the trimming behavior of the format set to the given value.
1836      *
1837      * @param ignoreSurroundingSpaces
1838      *            the trimming behavior, {@code true} to remove the surrounding spaces, {@code false} to leave the
1839      *            spaces as is.
1840      * @return A new CSVFormat that is equal to this but with the specified trimming behavior.
1841      */
1842     public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpaces) {
1843         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1844                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1845                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1846     }
1847 
1848     /**
1849      * Returns a new {@code CSVFormat} with conversions to and from null for strings on input and output.
1850      * <ul>
1851      * <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
1852      * records.</li>
1853      * <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
1854      * </ul>
1855      *
1856      * @param nullString
1857      *            the String to convert to and from {@code null}. No substitution occurs if {@code null}
1858      *
1859      * @return A new CSVFormat that is equal to this but with the specified null conversion string.
1860      */
1861     public CSVFormat withNullString(final String nullString) {
1862         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1863                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1864                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1865     }
1866 
1867     /**
1868      * Returns a new {@code CSVFormat} with the quoteChar of the format set to the specified character.
1869      *
1870      * @param quoteChar
1871      *            the quoteChar character
1872      * @return A new CSVFormat that is equal to this but with the specified character as quoteChar
1873      * @throws IllegalArgumentException
1874      *             thrown if the specified character is a line break
1875      */
1876     public CSVFormat withQuote(final char quoteChar) {
1877         return withQuote(Character.valueOf(quoteChar));
1878     }
1879 
1880     /**
1881      * Returns a new {@code CSVFormat} with the quoteChar of the format set to the specified character.
1882      *
1883      * @param quoteChar
1884      *            the quoteChar character, use {@code null} to disable
1885      * @return A new CSVFormat that is equal to this but with the specified character as quoteChar
1886      * @throws IllegalArgumentException
1887      *             thrown if the specified character is a line break
1888      */
1889     public CSVFormat withQuote(final Character quoteChar) {
1890         if (isLineBreak(quoteChar)) {
1891             throw new IllegalArgumentException("The quoteChar cannot be a line break");
1892         }
1893         return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, escapeCharacter, ignoreSurroundingSpaces,
1894                 ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
1895                 allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1896     }
1897 
1898     /**
1899      * Returns a new {@code CSVFormat} with the output quote policy of the format set to the specified value.
1900      *
1901      * @param quoteModePolicy
1902      *            the quote policy to use for output.
1903      *
1904      * @return A new CSVFormat that is equal to this but with the specified quote policy
1905      */
1906     public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
1907         return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy, commentMarker, escapeCharacter,
1908                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1909                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1910     }
1911 
1912     /**
1913      * Returns a new {@code CSVFormat} with the record separator of the format set to the specified character.
1914      *
1915      * <p>
1916      * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
1917      * only works for inputs with '\n', '\r' and "\r\n"
1918      * </p>
1919      *
1920      * @param recordSeparator
1921      *            the record separator to use for output.
1922      *
1923      * @return A new CSVFormat that is equal to this but with the specified output record separator
1924      */
1925     public CSVFormat withRecordSeparator(final char recordSeparator) {
1926         return withRecordSeparator(String.valueOf(recordSeparator));
1927     }
1928 
1929     /**
1930      * Returns a new {@code CSVFormat} with the record separator of the format set to the specified String.
1931      *
1932      * <p>
1933      * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
1934      * only works for inputs with '\n', '\r' and "\r\n"
1935      * </p>
1936      *
1937      * @param recordSeparator
1938      *            the record separator to use for output.
1939      *
1940      * @return A new CSVFormat that is equal to this but with the specified output record separator
1941      * @throws IllegalArgumentException
1942      *             if recordSeparator is none of CR, LF or CRLF
1943      */
1944     public CSVFormat withRecordSeparator(final String recordSeparator) {
1945         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1946                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1947                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1948     }
1949 
1950     /**
1951      * Returns a new {@code CSVFormat} with skipping the header record set to {@code true}.
1952      *
1953      * @return A new CSVFormat that is equal to this but with the specified skipHeaderRecord setting.
1954      * @see #withSkipHeaderRecord(boolean)
1955      * @see #withHeader(String...)
1956      * @since 1.1
1957      */
1958     public CSVFormat withSkipHeaderRecord() {
1959         return this.withSkipHeaderRecord(true);
1960     }
1961 
1962     /**
1963      * Returns a new {@code CSVFormat} with whether to skip the header record.
1964      *
1965      * @param skipHeaderRecord
1966      *            whether to skip the header record.
1967      *
1968      * @return A new CSVFormat that is equal to this but with the specified skipHeaderRecord setting.
1969      * @see #withHeader(String...)
1970      */
1971     public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord) {
1972         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1973                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1974                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1975     }
1976 
1977     /**
1978      * Returns a new {@code CSVFormat} with the record separator of the format set to the operating system's line
1979      * separator string, typically CR+LF on Windows and LF on Linux.
1980      *
1981      * <p>
1982      * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
1983      * only works for inputs with '\n', '\r' and "\r\n"
1984      * </p>
1985      *
1986      * @return A new CSVFormat that is equal to this but with the operating system's line separator string.
1987      * @since 1.6
1988      */
1989     public CSVFormat withSystemRecordSeparator() {
1990         return withRecordSeparator(System.getProperty("line.separator"));
1991     }
1992 
1993     /**
1994      * Returns a new {@code CSVFormat} to add a trailing delimiter.
1995      *
1996      * @return A new CSVFormat that is equal to this but with the trailing delimiter setting.
1997      * @since 1.3
1998      */
1999     public CSVFormat withTrailingDelimiter() {
2000         return withTrailingDelimiter(true);
2001     }
2002 
2003     /**
2004      * Returns a new {@code CSVFormat} with whether to add a trailing delimiter.
2005      *
2006      * @param trailingDelimiter
2007      *            whether to add a trailing delimiter.
2008      *
2009      * @return A new CSVFormat that is equal to this but with the specified trailing delimiter setting.
2010      * @since 1.3
2011      */
2012     public CSVFormat withTrailingDelimiter(final boolean trailingDelimiter) {
2013         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
2014                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
2015                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
2016     }
2017 
2018     /**
2019      * Returns a new {@code CSVFormat} to trim leading and trailing blanks.
2020      *
2021      * @return A new CSVFormat that is equal to this but with the trim setting on.
2022      * @since 1.3
2023      */
2024     public CSVFormat withTrim() {
2025         return withTrim(true);
2026     }
2027 
2028     /**
2029      * Returns a new {@code CSVFormat} with whether to trim leading and trailing blanks.
2030      *
2031      * @param trim
2032      *            whether to trim leading and trailing blanks.
2033      *
2034      * @return A new CSVFormat that is equal to this but with the specified trim setting.
2035      * @since 1.3
2036      */
2037     public CSVFormat withTrim(final boolean trim) {
2038         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
2039                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
2040                 skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
2041     }
2042 }