首页 > 解决方案 > Java BufferedFileReader 跳过第一行

问题描述

我正在尝试使用 BufferedFileReader 读取包含已保存信息的文档。它工作得很好,但它总是跳过代码的第一行。是因为我在 for 循环中调用 readLine() 吗?如果是这样我怎么能改变它?

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();
    }


}

标签: javaswingiotext-files

解决方案


您的问题涉及几个步骤,但对于您而言,最重要的问题是当数据以三行一组的形式呈现时,如何有效和安全地读取文本文件中保存的数据,例如:

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

当然,其中的名字被真实姓名替换,同样的年龄?替换为实数。

如果您要走 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

    // ....

}

这样,如果文本文件中的任何一个Strings丢失了,整个while循环就结束了,不会得到坏数据。

其他建议,创建一个普通的 Java 对象来保存您的 Person 数据、姓名和年龄,一个具有 3 个字段的类,其中 2 个是名称的字符串,一个用于年龄的 int 字段。给它一个像样的构造函数,getter 方法......例如:

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
}

好的,如何将这些信息显示到 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 被创建并填充了数据。

好的,假设一个名为 PersonData.txt 的数据文件与我们的类文件位于同一目录中,如下所示:

在此处输入图像描述

并假设该文件保存我们的数据,如下所示:

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 类,我们可以创建一个 GUI 来保存和显示我们的数据,如下所示:

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();
        }
    }
}

当显示时,它看起来像:

在此处输入图像描述


推荐阅读