Not sure if you need to go as far as using an external library (and taking the usually implied performance hit). It's a pretty simple thing to implement. And if nothing else, it always helps to know what's going on behind the scenes in such a library:
public List<Person> readFile(String fileName) throws IOException {
List<Person> result = new ArrayList<Person>();
BufferedReader br = new BufferedReader(new FileReader(new File(fileName)));
try {
// Read first line
String line = br.readLine();
// Make sure file has correct headers
if (line==null) throw new IllegalArgumentException("File is empty");
if (!line.equals("name,surname,shoesize,sex"))
throw new IllegalArgumentException("File has wrong columns: "+line);
// Run through following lines
while ((line = br.readLine()) != null) {
// Break line into entries using comma
String[] items = line.split(",");
try {
// If there are too many entries, throw a dummy exception, if
// there are too few, the same exception will be thrown later
if (items.length>4) throw new ArrayIndexOutOfBoundsException();
// Convert data to person record
Person person = new Person();
person.setName ( items[0] );
person.setSurname ( items[1] );
person.setShoeSize(Double .parseDouble (items[2]));
person.setSex (Boolean.parseBoolean(items[3]));
result.add(person);
} catch (ArrayIndexOutOfBoundsException|NumberFormatException|NullPointerException e) {
// Caught errors indicate a problem with data format -> Print warning and continue
System.out.println("Invalid line: "+ line);
}
}
return result;
} finally {
br.close();
}
}
Note that the catch statement uses Java 7 multi-catch. For older Java versions, either split it into 3 catch blocks or replace ArrayIndexOutOfBoundsException|NumberFormatException|NullPointerException
with Exception
. The latter is usually discouraged as it masks and ignores all other exceptions as well, but in a simple example like this, the risk is probably not too high.
This answer, unfortunately, is specific to your problem, but given that it is very straight forward, it should be easy to adapt to other situations as well...
Another neat thing you can do is to match line
inside the while loop with a regular expression rather than simply splitting it based on a comma. That way you could also implement data validation in one shot (for example only match a sensible number for shoe size).
Note that the above implementation doesn't work if you have names that contain commas which are then enclosed in quotes (like "Jackson, Jr." as a last name). You can cover this case "easily" if you use regular expressions as described above, or by checking the first letter of the last name and if it is a quotation mark, combine item[1] with item[2] and use item[3] and item[4] instead for the shoesize and sex. This special case will likely be covered by most of the external libraries suggested here, so if you're not worried about any dependencies, licensing issues, and performance hits, those might be the easier way out...