Как сообщение об исключении может превзойти выполненную печатную строку - PullRequest
0 голосов
/ 24 января 2019

Я читаю поля из файла .csv, разделенного ";"точка с запятой.И я написал исключения, чтобы справиться с возможными отклонениями.Но если есть исключение, NetBeans зачитывает сообщение об ошибке перед последней строкой.

Вот так будет выглядеть вывод: enter image description here

ДонНе понимаю, как это возможно, что более поздняя строка в коде может распечатывать преимущественно.Это весь мой код:

public static void reader(String fileName) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
        String line;
        List<String> lineHolder = new ArrayList<>();
        StringTokenizer divider;
        String formatter = "%2s|%-30s|%-30s|%10s|%n";

        String separator = "----------";
        System.out.format("ID|%-30s|%-30s|birth date|%n", "name", "email");
        System.out.print("--+" + separator + separator + separator 
                + "+" + separator + separator + separator + "+" 
                + separator + "+\n");

        while ((line = br.readLine()) != null){
            if (line.startsWith("#", 0))
                continue;
            if (!line.contains(";")) {
                throw new IOException("too less data or not proper delimiter");
            }
            divider = new StringTokenizer(line, ";");
            lineHolder = arrayFiller(divider);
            dataChecker(lineHolder, line);
            System.out.format(formatter, lineHolder.get(0), lineHolder.get(1)
                , lineHolder.get(2), lineHolder.get(3));
        }
    } catch (FileNotFoundException ex) {
        System.err.println("The file not found.");
    } catch (IOException ex){
        System.err.println(ex.getMessage());
    }
    System.out.print("\n");
}

public static ArrayList<String> arrayFiller(StringTokenizer divider) {
    ArrayList<String> lineHolder = new ArrayList<>();
    while (divider.hasMoreTokens()) {
        lineHolder.add(divider.nextToken());
    }
    return lineHolder;
}

Это исключения:

public static void dataChecker(List<String> lineHolder, String line) throws IOException {
    if (lineHolder.size() < 4) {
        throw new IOException("too less data or not proper delimiter");
    } else if (lineHolder.size() > 4) {
        throw new IOException("too much data");
    } else if (lineHolder.get(0).length() > 2 
            || !Pattern.matches("[0-9]+", lineHolder.get(0))) {
        throw new IOException("Error during reading the file: "
                + "not proper ID field format");
    } else if (lineHolder.get(1).length() > 30 
            || !Pattern.matches("[a-zA-ZíÍöÖüÜóÓőŐúÚűŰáÁéÉ. ]+", lineHolder.get(1))) {
        throw new IOException("Error during reading the file: "
                + "not proper Name field format");
    } else if (lineHolder.get(2).length() > 30 
            || !Pattern.matches("[a-zA-Z0-9@. ]+", lineHolder.get(2))) {
        throw new IOException("Error during reading the file: "
                + "not proper Email field format");
    } else if (lineHolder.get(3).length() > 10 || dateFormatter(lineHolder.get(3))) {
        throw new IOException("Error during reading the file: "
                + "not proper Birth date field format");
    } 
}

public static boolean dateFormatter(String datum) {
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    try {
        LocalDate changedDate = LocalDate.parse(datum, dtf);
        return false;
    } catch (DateTimeParseException ex) {
        return true;
    }
}

И исходный файл:

#ID;name;email;birth date
1,Jakob George,gipszjakab@gmail.com,1981-11-23
2;Susan Smith;usa@gmail.com;1982-12-01
3;Poul Drake;gameover@gmail.com;1990-01-02
4;Isaac Wheather;ruck%sack@freemail.hu;1988-01-22
5;George T. Benson;bigman@hotmail.com;1977-08-12

Я пытался поставить метод (держатель исключений) в метод reader(), но результат тот же.Как это возможно и что я сделал не так?

Ответы [ 2 ]

0 голосов
/ 24 января 2019
    String separator = "----------";
    System.out.format("ID|%-30s|%-30s|birth date|%n", "name", "email");
    System.out.print("--+" + separator + separator + separator 
            + "+" + separator + separator + separator + "+" 
            + separator + "+\n");
    System.out.flush();
    while ((line = br.readLine()) != null)

Поскольку System.out и System.err из разных выходных потоков, они не будут ждать завершения друг друга. Очистка буферной памяти сразу после того, как оператор print сработает.

0 голосов
/ 24 января 2019

Сообщения об ошибках печатаются через другой поток вывода. Стандартный поток вывода stdout предназначен для обычной регистрации / вывода, ошибки (через System.err.println) переходят на stderr. Ваша консоль / терминал показывает оба, но они не будут ждать друг друга, чтобы закончить печатать материал.

РЕДАКТИРОВАТЬ: Может быть это тоже помогает.

РЕДАКТИРОВАТЬ 2: Если вы измените ошибку для печати в файл, вы потеряете вывод ошибки в консоли / терминале. Но может быть, это нормально для вас? Как это:

//set err out to print to file
PrintStream ps = new PrintStream("err.log");
System.setErr(ps);

//cause exception for testing it
String s = null;
s.length();

Если вы хотите, чтобы на консоль / терминал выводились и ошибки, и стандартный вывод, то нет способа контролировать синхронизацию обоих потоков, поскольку каждая напечатанная строка является независимой операцией.

...