#41 CSVWriter ignores errors from the underlying Writer

closed-fixed
None
5
2009-12-10
2009-12-10
Anonymous
No

CSVWriter wraps its passed Writer in PrintWriter which has in its Javadoc:
"Methods in this class never throw I/O exceptions. The client may inquire as to whether any errors have occurred by invoking checkError()."

CSVWriter never calls checkError() or similar. I found this bug because I was writing out large CSV files that filled up my /tmp/ - this didn't result in an error at the time, but just left me with partially complete CSV files.

I think CSVWriter should either (A) use a Writer that throws IOException in this case (B) call checkError at some defined point (maybe on every flush?) or (C) provide me with a method to call checkError() on the PrintWriter.

Discussion

  • Nobody/Anonymous

    Here's a patch to use BufferedWriter instead of PrintWriter - this means that various methods in CSVWriter now throw IOException where they didn't previously, so this will break compatibility with people who expect the old interface.

    Let me know if there's a better diff format for you, and I'll do the diff again - gbills AT funnelback DOT com or george DOT s DOT bills AT gmail DOT com.

    This has got fairly minimal testing over on my side, but seems to work:

    Caused by: java.io.IOException: No space left on device
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:297)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:220)
    at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281)
    at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:124)
    at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
    at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:128)
    at java.io.BufferedWriter.write(BufferedWriter.java:229)
    at java.io.Writer.write(Writer.java:157)
    at au.com.bytecode.opencsv.CSVWriter.writeNext(CSVWriter.java:368)

    --- trunk/external/opencsv-2.1.patched/src/au/com/bytecode/opencsv/CSVWriter.java 2009-12-10 02:47:56 UTC (rev 17370)
    +++ trunk/external/opencsv-2.1.patched/src/au/com/bytecode/opencsv/CSVWriter.java 2009-12-10 02:51:26 UTC (rev 17371)
    @@ -16,9 +16,19 @@
    limitations under the License.
    */

    -import java.io.*;
    +import java.io.BufferedWriter;
    +import java.io.Closeable;
    +import java.io.IOException;
    +import java.io.Reader;
    +import java.io.Writer;
    import java.math.BigDecimal;
    -import java.sql.*;
    +import java.sql.Clob;
    +import java.sql.ResultSet;
    +import java.sql.ResultSetMetaData;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.sql.Types;
    import java.text.SimpleDateFormat;
    import java.util.List;

    @@ -34,7 +44,7 @@

    private Writer rawWriter;

    - private PrintWriter pw;
    + private BufferedWriter bw;

    private char separator;

    @@ -152,7 +162,7 @@
    */
    public CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd) {
    this.rawWriter = writer;
    - this.pw = new PrintWriter(writer);
    + this.bw = new BufferedWriter(writer);
    this.separator = separator;
    this.quotechar = quotechar;
    this.escapechar = escapechar;
    @@ -166,15 +176,16 @@
    * @param allLines
    * a List of String[], with each String[] representing a line of
    * the file.
    + * @throws IOException
    */
    - public void writeAll(List<String[]> allLines) {
    + public void writeAll(List<String[]> allLines) throws IOException {
    for (String[] line : allLines) {
    writeNext(line);
    }
    }

    protected void writeColumnNames(ResultSetMetaData metadata)
    - throws SQLException {
    + throws SQLException, IOException {

    int columnCount = metadata.getColumnCount();

    @@ -182,7 +193,7 @@
    for (int i = 0; i < columnCount; i++) {
    nextLine[i] = metadata.getColumnName(i + 1);
    }
    - writeNext(nextLine);
    + writeNext(nextLine);
    }

    /**
    @@ -329,7 +340,7 @@
    * a string array with each comma-separated element as a separate
    * entry.
    */
    - public void writeNext(String[] nextLine) {
    + public void writeNext(String[] nextLine) throws IOException {

    if (nextLine == null)
    return;
    @@ -354,7 +365,7 @@
    }

    sb.append(lineEnd);
    - pw.write(sb.toString());
    + bw.write(sb.toString());

    }

    @@ -386,7 +397,7 @@
    */
    public void flush() throws IOException {

    - pw.flush();
    + bw.flush();

    }

    @@ -398,7 +409,7 @@
    */
    public void close() throws IOException {
    flush();
    - pw.close();
    + bw.close();
    rawWriter.close();
    }

     
  • Scott Conway

    Scott Conway - 2009-12-10

    I added a checkError method to csvWriter which returns the checkError from PrintWriter and it is currently merged to the trunk. This way there is no impact to current users.

     
  • Scott Conway

    Scott Conway - 2009-12-10
    • status: open --> closed
     
  • Scott Conway

    Scott Conway - 2009-12-10
    • assigned_to: nobody --> sconway
    • status: closed --> closed-fixed
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks