Java读取文本文件多对象问题:如何获取全部对象而非仅首个?
嘿,我来帮你解决这个只能读到第一个对象的问题!这大概率是因为你的写入和读取逻辑没配合好——要么是写入时没把所有对象都正确存进文件,要么是读取时只执行了一次读取就停了。下面给你两种常见的解决方案,对应不同的文件存储方式:
方案一:使用Java对象序列化(推荐)
这种方式适合不需要手动查看文件内容的场景,操作简单且类型安全。
首先,必须确保你的Processedfile类实现Serializable接口,否则序列化会失败:
import java.io.Serializable; public class Processedfile implements Serializable { private String filename; private int countrow; private String dateformat; // 记得添加getter、setter方法和必要的构造方法 }
正确的写入逻辑(写入整个列表)
直接把整个List<Processedfile>写入文件,这样读取时一次就能拿到所有对象:
public void writeReportTextFile(List<Processedfile> processfiles) { try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("processed_files.dat"))) { oos.writeObject(processfiles); // 一次性写入整个列表 } catch (IOException e) { e.printStackTrace(); } }
对应的读取逻辑
读取时直接把整个列表从文件中读出来:
public List<Processedfile> readReportTextFile() { List<Processedfile> processfiles = new ArrayList<>(); try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("processed_files.dat"))) { // 强制类型转换为List<Processedfile> processfiles = (List<Processedfile>) ois.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } return processfiles; }
如果你是逐个写入单个Processedfile对象(不推荐,但如果之前的代码是这么写的),读取时需要循环读取直到文件末尾:
逐个写入的逻辑
public void writeReportTextFile(List<Processedfile> processfiles) { try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("processed_files.dat"))) { for (Processedfile pf : processfiles) { oos.writeObject(pf); // 逐个写入每个对象 } } catch (IOException e) { e.printStackTrace(); } }
对应的循环读取逻辑
public List<Processedfile> readReportTextFile() { List<Processedfile> processfiles = new ArrayList<>(); try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("processed_files.dat"))) { while (true) { try { Processedfile pf = (Processedfile) ois.readObject(); processfiles.add(pf); } catch (EOFException e) { // 捕获文件末尾异常,退出循环 break; } } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } return processfiles; }
方案二:自定义文本格式(适合需要手动查看文件内容的场景)
如果需要文件是可读的文本格式,可以自定义字段分隔符(比如|),每行存储一个对象的信息。
写入逻辑
把每个Processedfile对象转成字符串,逐行写入文件:
public void writeReportTextFile(List<Processedfile> processfiles) { try (PrintWriter writer = new PrintWriter(new FileWriter("processed_files.txt"))) { for (Processedfile pf : processfiles) { // 用|分隔各个字段,注意如果字段本身包含|,需要先转义 String line = pf.getFilename() + "|" + pf.getCountrow() + "|" + pf.getDateformat(); writer.println(line); } } catch (IOException e) { e.printStackTrace(); } }
读取逻辑
逐行读取文件,拆分字符串并还原成Processedfile对象:
public List<Processedfile> readReportTextFile() { List<Processedfile> processfiles = new ArrayList<>(); try (BufferedReader reader = new BufferedReader(new FileReader("processed_files.txt"))) { String line; // 循环读取每一行,直到文件末尾 while ((line = reader.readLine()) != null) { String[] parts = line.split("\\|"); // 注意转义|,因为它是正则表达式的特殊字符 Processedfile pf = new Processedfile(); pf.setFilename(parts[0]); pf.setCountrow(Integer.parseInt(parts[1])); pf.setDateformat(parts[2]); processfiles.add(pf); } } catch (IOException e) { e.printStackTrace(); } return processfiles; }
额外注意事项
- 如果用序列化方式,不要随意修改
Processedfile类的结构(比如新增/删除字段),否则可能导致读取旧文件时抛出InvalidClassException。如果必须修改,可以手动指定serialVersionUID。 - 如果用自定义文本格式,要确保字段中不包含分隔符,或者提前对分隔符进行转义,避免拆分字符串时出错。
- 如果需要追加写入文件,序列化方式要注意:直接用追加模式会导致文件头重复,读取失败。建议每次写入整个列表,或者改用自定义文本格式的追加写入。
内容的提问来源于stack exchange,提问作者Madhavaraman
相关产品推荐
相关产品推荐

