javafilereaderbuffered

Is there a function to specify a message when reading in a file if the line doesn’t follow a certain pattern


I am making a Class called Book that represents books that have a title, an author and a year, when they won the award.

I have a method getList which should read in the data from a csv file and if a line doesn’t follow the pattern title,author,year then a message should be written to the standard error stream. I am having trouble determine how to specify the error message.

I can read in the file using BufferedReader

However, when it comes verifying all 3 values are there (title, author, year) I am not sure where to start. I imagine I need 3 variables which would check if (year, author, etc) is missing in one of the lines of the csv. I'm new to buffered reader and not sure how to go about this. any help is appreciated

I have looked on the internet and haven't found exactly what I'm looking for

  package books;

 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.List;

 public class Book implements Comparable<Book> {
private String title;
private String author;
private int year;

/**
 * @param title
 * @param author
 * @param year
 */
public Book(String title, String author, int year) {
    this.title = title;
    this.author = author;
    this.year = year;
}

public String getTitle() {
    return title;
}

public String getAuthor() {
    return author;
}

public int getYear() {
    return year;
}

@Override
public String toString() {
    return title + " by " + author + " (" + year + ")";

}

public static List<Book> getList(String file) {

    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        while (reader.ready()) {

            System.out.println(reader.readLine());
        }
        System.out.println();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

@Override
public int compareTo(Book o) {
    // TODO Auto-generated method stub
    return 0;
}

  }

tests app

 package books;


 public class BookApp {

public static void main(String[] args)  {
    Book book = new Book ("Harry Potter and the Sorcerer's Stone", "J. K. Rowling", 1997);
    System.out.println(book.toString());

    System.out.println();
    book.getList("src/books/books.csv");
}
}

Solution

  • Heey you can use the following code to parse and validate the books:

    
    public static List<Book> getList(String file) {
    // create a new list of books
        List<Book> books = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            while (reader.ready()) {
                // read line of reader
                String bookLine = reader.readLine();
                Book book = toBook(bookLine);
                if (book != null) { //only add the book if it is non empty
                    books.add(book);
                }
            }
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return books;
    }
    
    private static Book toBook(String bookLine) {
        String[] bookParts = bookLine.split(",");
        if (bookParts.length < 3) { //validate if all three parts are present
            System.err.println(String.format("The line %s did not contain all parts", bookLine));
            return null;
        }
        if (bookParts[0].trim().isEmpty()) { // validate the book has a title
            System.err.println(String.format("The line %s did contain an empty title", bookLine));
            return null;
        }
    
        if (bookParts[1].trim().isEmpty()) { // validate the book has an author
            System.err.println(String.format("The line %s did contain an empty author", bookLine));
            return null;
        }
        if (!bookParts[2].trim().matches("\\d{4}")) { // checks if the year (3rd part is a number. Where \\d is for numeric and {4} means 4 digits)
            System.err.println(String.format("The line %s did contain a non-numeric value as year", bookLine));
            return null;
        }
        return new Book(bookParts[0], bookParts[1], Integer.parseInt(bookParts[2]));
    }