【问题标题】:How can I read and write objects from an arraylist?如何从数组列表中读取和写入对象?
【发布时间】:2013-04-24 18:42:20
【问题描述】:

我正在我的 UserArchive 类并从我的 User 类添加用户对象:

public class UserArchive implements Serializable {
ArrayList<User> list = new ArrayList<User>();

// Inserts a new User-object
public void regCustomer(User u) {
    list.add(u);
}

阅读和编写此列表的最佳方式是什么?

我觉得这样写是对的吗?

    public void writeFile() {
    File fileName = new File("testList.txt");
    try{
        FileWriter fw = new FileWriter(fileName);
        Writer output = new BufferedWriter(fw);
        int sz = list.size();
        for(int i = 0; i < sz; i++){
            output.write(list.get(i).toString() +"\n");
        }
        output.close();
    } catch(Exception e){
        JOptionPane.showMessageDialog(null, "Kan ikke lage denne filen");
    }

我尝试使用 BufferedReader 读取文件,但无法让 list.add(line) 工作:

    public void readFile() {
    String fileName = "testList.txt";
    String line;

    try{
        BufferedReader input = new BufferedReader(new FileReader(fileName));
        if(!input.ready()){
            throw new IOException();
        }
        while((line = input.readLine()) != null){
            list.add(line);
        }
        input.close();
    } catch(IOException e){
        System.out.println(e);
    }
}

我知道问题在于该行是一个字符串,并且应该是一个用户。是我不能使用 BufferedReader 来做到这一点的问题吗?如果是这样,我应该如何读取文件?

【问题讨论】:

  • 阅读this 文章。
  • 否则,执行public static User parse(String line) {}
  • "I can't get it to work",您的意思是list.add(line) 不起作用,还是您还有其他问题?跨度>
  • 是的,我的意思是,对不起,谢谢
  • 如果输入流没有准备好,不要抛出异常。只需阅读它!读取将阻塞,直到流准备好。

标签: java arraylist bufferedreader filewriter


【解决方案1】:

想象一个简单的 User 类,如下所示:

public class User {
    private int id;
    private String username;

    // Constructors, etc...

    public String toString() {
        StringBuilder sb = new StringBuilder("#USER $");
        sb.append(id);
        sb.append(" $ ");
        sb.append(username);
        return sb.toString();
    }
}

对于具有id = 42username = "Dummy" 的用户,用户字符串表示为:

#USER $ 42 $ Dummy

乍一看,您的代码似乎成功地将这些字符串写入文本文件(我还没有测试过)。
所以,问题在于读回信息。这从(在这种情况下)格式化文本中提取有意义的信息,通常称为解析

您想从您阅读的行中解析此信息。
调整你的代码:

BufferedReader input = null;
try {
    input = new BufferedReader(new FileReader(fileName));
    String line;
    while((line = input.readLine()) != null) {
        list.add(User.parse(line));
    }
} catch(IOException e) {
    e.printStackTrace();
} finally {
    if (input != null) { input.close(); }
}

注意细微差别。我已将list.add(line) 替换为list.add(User.parse(line))。这就是魔法发生的地方。让我们继续实现解析方法。

public class User {
    private int id;
    private String username;

    // ...

    public static User parse(String line) throws Exception {
        // Let's split the line on those $ symbols, possibly with spaces.
        String[] info = line.split("[ ]*\\$[ ]*");
        // Now, we must validate the info gathered.
        if (info.length != 3 || !info[0].equals("#USER")) {
            // Here would go some exception defined by you.
            // Alternatively, handle the error in some other way.
            throw new Exception("Unknown data format.");
        }
        // Let's retrieve the id.
        int id;
        try {
            id = Integer.parseInt(info[1]);
        } catch (NumberFormatException ex) {
            throw new Exception("Invalid id.");
        }
        // The username is a String, so it's ok.
        // Create new User and return it.
        return new User(id, info[2]);
    }
}

你就完成了!

【讨论】:

  • 我现在正在尝试这种方式,但在 InvalidUserDataException 上出现错误,eclipse 要求我创建类 InvalidUserDataException 或使用其他东西,例如:InvalidClassException
  • 对不起,我忘了补充 InvalidUserDataException 将是您定义的异常,或者,使用您喜欢的其他方式来处理错误状态。我现在正在更新答案。
【解决方案2】:

如果用户对象不复杂,最简单的方法是将每个用户转换为 csv 格式。

例如,您的用户类应如下所示

public class User {

private static final String SPLIT_CHAR = ",";
private String field1;
private String field2;
private String field3;

public User(String csv) {
    String[] split = csv.split(SPLIT_CHAR);
    if (split.length > 0) {
        field1 = split[0];
    }

    if (split.length > 1) {
        field2 = split[1];
    }

    if (split.length > 2) {
        field3 = split[2];
    }
}

/**
 * Setters and getters for fields
 * 
 * 
 */

public String toCSV() {
    //check null here and pass empty strings
    return field1 + SPLIT_CHAR + field2 + SPLIT_CHAR + field3;
}

  }



}

在编写对象调用时
output.write(list.get(i).toCSV() +"\n"); 阅读时你可以打电话 list.add(new User(line));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 2019-02-12
    • 1970-01-01
    • 2011-10-09
    • 2011-03-26
    • 1970-01-01
    相关资源
    最近更新 更多