5
\$\begingroup\$

Here is my class to read a csv file and I was wondering if there is any improvements that I should do. I feel there are some performance improvements or in exception handling because I just took IO exceptions.

package com.mypackage.utils;
import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.enums.CSVReaderNullFieldIndicator;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;

public class FileReader {

    private String path;
    private CSVReader reader;
    private List<String> linesList;
    private Set<List<String>> splitLinesSet;

    public FileReader(String path) {
        this.path = path;
    }

    public boolean readFile() {

        this.splitLinesSet = new HashSet<>();

        try {
            File file = Paths.get(path).toFile();
            reader = new CSVReaderBuilder(new java.io.FileReader(file))
                    .withCSVParser(new CSVParserBuilder()
                            .withSeparator('|')
                            .withFieldAsNull(CSVReaderNullFieldIndicator.NEITHER).build())
                    .build();
            read();
            reader.close();
        } catch (IOException e) {
            System.err.println("Error in reading CSV: " + e.getMessage());
            return false;
        }

        return true;
    }

    public Set<List<String>> getSplitLinesSet() {
        return splitLinesSet;
    }

    private void read() throws IOException {
        String[] lines;
        while ((lines = reader.readNext()) != null) {
            linesList = new ArrayList<>();
            Collections.addAll(linesList, lines);
            splitLinesSet.add(linesList);
        }
    }
}
\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

I tend to advocate not passing things around which need to be closed, thus my advice is:

  • inline the read method
  • remove the reader field, and
  • ... declare the same as a local variable
  • perferably, declare that local reader variable in a try-with-resources block and throw out the explicit close()-call

Note that these changes are just about robustness and maintainability and will not affect performance or error handling.

Edit, after the comment asking for code edit. (Note: sorry, I am a newbie in the code review community, I hope this does not break any principle here.)

public class FileReader {

    private String path;
    private List<String> linesList;
    private Set<List<String>> splitLinesSet;

    public FileReader(String path) {
        this.path = path;
    }

    public boolean readFile() {

        this.splitLinesSet = new HashSet<>();
        File file = Paths.get(path).toFile();

        try (
            CSVReader reader = new CSVReaderBuilder(new java.io.FileReader(file))
                    .withCSVParser(new CSVParserBuilder()
                            .withSeparator('|')
                            .withFieldAsNull(CSVReaderNullFieldIndicator.NEITHER).build())
                    .build();
            ) {
            String[] lines;
            while ((lines = reader.readNext()) != null) {
                linesList = new ArrayList<>();
                Collections.addAll(linesList, lines);
                splitLinesSet.add(linesList);
            }
        } catch (IOException e) {
            System.err.println("Error in reading CSV: " + e.getMessage());
            return false;
        }

        return true;
    }

    public Set<List<String>> getSplitLinesSet() {
        return splitLinesSet;
    }
}

Note: this was just syntactic shuffling of lines in a text editor - I have not put this through an IDE or a compiler, but I think it shows the principles.

\$\endgroup\$
1
  • \$\begingroup\$ @PHA : See edit, and good luck :) \$\endgroup\$
    – mtj
    Dec 16, 2016 at 12:24
0
\$\begingroup\$

FileReader should be avoided, because it relies on a default encoding. We should specify explicitly the encoding used.

CSVParser parser = new CSVParserBuilder().withSeparator('|').build();

try (BufferedReader br = Files.newBufferedReader(myPath, 
        StandardCharsets.UTF_8);
        CSVReader reader = new CSVReaderBuilder(br).withCSVParser(parser)
                .build()) {
...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.