Java BufferedFileReader пропускает первую строку - PullRequest
0 голосов
/ 15 декабря 2018

Я пытаюсь использовать BufferedFileReader для чтения документа с сохраненной информацией.Работает хорошо, но всегда пропускает первую строку кода.Это потому, что я вызываю readLine () в цикле for?Если так, как я мог изменить это?

private void createViewUser() {

    String[] stringFirstName = new String[10];
    String[] stringName = new String[10];
    String[] stringAge= new String[10];

    try {
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);

        for (int i = 0; br.readLine() != null; i++) {

            stringFirstName[i] = br.readLine();
            stringName[i] = br.readLine();
            stringAge[i] = br.readLine();

            firstname[i] = new JTextField();
            firstname[i].setBounds(100, 100 + 50 * i, 100, 30);
            view.add(firstname[i]);

            name[i] = new JTextField();
            name[i].setBounds(200, 100 + 50 * i, 100, 30);
            view.add(name[i]);

            age[i] = new JTextField();
            age[i].setBounds(300, 100 + 50 * i, 100, 30);
            view.add(age[i]);

            firstname[i].setText(stringFirstName[i]);
            name[i].setText(stringName[i]);
            age[i].setText(stringAge[i]);

        }
        fr.close();
        br.close();



    } catch (IOException ex) {
        ex.printStackTrace();
    }


}

Ответы [ 4 ]

0 голосов
/ 16 декабря 2018

Ваш вопрос включает в себя несколько этапов, но наиболее важная проблема для ваших целей заключается в том, как эффективно и безопасно прочитать данные, хранящиеся в текстовом файле, когда данные представлены группами из трех строк, что-то вроде:

first_name_1
last_name_1
age_1
first_name_2
last_name_2
age_2
first_name_3
last_name_3
age_3
first_name_4
last_name_4
age_4

где, конечно, имена заменяются настоящими именами, а также age_?заменяется действительным числом.

Если вы собираетесь идти по маршруту BufferedReader, я думаю, что самое безопасное, что нужно сделать, это получить все три строки в каждой группе в цикле while.логическое условие, что-то вроде:

BufferedReader reader = new BufferedReader(....);

// declare empty Strings first
String firstName = "";
String lastName = "";
String ageString = ""; // need to get age *first* as a String

while ((firstName = reader.readLine()) != null         // get all 3 Strings here
        && (lastName = reader.readLine()) != null
        && (ageString = reader.readLine()) != null) {  // boolean condition ends here
    int age = Integer.parseInt(ageString.trim());    // NumberFormatException risk here

    // ....

}

Таким образом, если какая-либо из строк в текстовом файле отсутствует, весь цикл while заканчивается и плохие данные не получаются.

Otherрекомендации, создайте простой старый Java-объект для хранения ваших данных Person, имен и возраста, класса с 3 полями, 2, которые являются строками для имен, и одним целым полем для возраста.Дайте ему достойный конструктор, методы получения .... Например:

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + "]";
    }

}

Таким образом, вышеприведенный цикл while можно использовать для простого создания объектов Person:

List<Person> persons = new ArrayList<>();  // an ArrayList of Person to hold the data

while ((firstName = reader.readLine()) != null              // get all 3 Strings here
        && (lastName = reader.readLine()) != null
        && (ageString = reader.readLine()) != null) {       // the while loop ends here
    int age = Integer.parseInt(ageString.trim());

    Person person = new Person(firstName, lastName, age);   // create a new Person object 
    persons.add(person);                                    // put it into the arraylist
}

OKкак насчет отображения этой информации в JTable - это просто.

Создайте DefaultTableModel с правильными именами столбцов:

private static final String[] COL_NAMES = { "First Name", "Last Name", "Age" };
private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);

, а затем создайте JTable с этой моделью:

private JTable table = new JTable(model);

Затем выполните итерацию по ArrayList<Person> и заполните нашу модель данными:

for (Person person : personList) {
    Vector<Object> rowData = new Vector<>();
    rowData.add(person.getFirstName());
    rowData.add(person.getLastName());
    rowData.add(person.getAge());
    model.addRow(rowData);
}

, и JTable будет создан и заполнен данными, просто так.

OKпри условии, что файл данных с именем PersonData.txt находится в том же каталоге, что и наши файлы классов, например:

enter image description here

и при условии, что этот файлхранит наши данные следующим образом:

John
Smith
21
Fred
Flinstone
53
Barny
Rubble
52
Mary
Contrary
22
Bo
Peep
12
Donald
Trump
75
Donald
Duck
40
Mickey
Mouse
45
Minnie
Mouse
41
Ebenezer
Scrooge
80
Bob
Cratchit
33
Ralph
Kramden
55
Alice
Kramden
48
Ed
Norton
54

Затем, используя наш класс Person.java, мы можем создать графический интерфейс для хранения и отображения наших данных следующим образом:

import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

@SuppressWarnings("serial")
public class PersonDisplay extends JPanel {
    private static final String[] COL_NAMES = { "First Name", "Last Name", "Age" };
    private static final String PERSON_DATA_PATH = "PersonData.txt";
    private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);
    private JTable table = new JTable(model);

    public PersonDisplay(List<Person> personList) {
        for (Person person : personList) {
            Vector<Object> rowData = new Vector<>();
            rowData.add(person.getFirstName());
            rowData.add(person.getLastName());
            rowData.add(person.getAge());
            model.addRow(rowData);
        }

        setLayout(new BorderLayout());
        add(new JScrollPane(table));
    }

    private static void createAndShowGui(List<Person> personList) {
        PersonDisplay mainPanel = new PersonDisplay(personList);

        JFrame frame = new JFrame("Person Display");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static List<Person> readInPersons(InputStream is) throws IOException {
        List<Person> persons = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String firstName = "";
        String lastName = "";
        String ageString = "";

        while ((firstName = reader.readLine()) != null 
                && (lastName = reader.readLine()) != null
                && (ageString = reader.readLine()) != null) {
            int age = Integer.parseInt(ageString.trim());
            Person person = new Person(firstName, lastName, age);
            persons.add(person);
        }

        return persons;
    }

    public static void main(String[] args) {
        try {
            InputStream inputStream = PersonDisplay.class.getResourceAsStream(PERSON_DATA_PATH);
            List<Person> personList = readInPersons(inputStream);
            SwingUtilities.invokeLater(() -> createAndShowGui(personList));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

и при отображении,это будет выглядеть так:

enter image description here

0 голосов
/ 15 декабря 2018

вы читаете первую строку в цикле for:

for (int i = 0; br.readLine() /* HERE*/ != null; i++) {

Вы можете сделать что-то вроде этого:

String line = br.readLine();
for(int i = 0; line != null ; i++){
       stringFirstName[i] = line;
       line = br.readLine();
}
0 голосов
/ 15 декабря 2018

Здравствуйте, вы можете запустить String var, чтобы исправить это:

String line = br.readLine();

for (int i = 0; line != null; i++) {
    stringFirstName[i] = line;
    stringName[i] = br.readLine();
    stringAge[i] = br.readLine();

Это не работает, потому что загружена первая строка для проверки цикла for (int i = 0; br.readLine() != null; i++) {

Удачи.

0 голосов
/ 15 декабря 2018

Точно, каждый раз перед входом в цикл for ваша программа читает строку и проверяет, не является ли она нулевой.Больше вы также пропустите строку из-за этого условия.(не уверен, желателен он или нет) Вы сами получили ответ;)

...