Java - 如何将我的 ArrayList 写入文件,并将该文件读取(加载)到原始 ArrayList?
Posted
技术标签:
【中文标题】Java - 如何将我的 ArrayList 写入文件,并将该文件读取(加载)到原始 ArrayList?【英文标题】:Java - How Can I Write My ArrayList to a file, and Read (load) that file to the original ArrayList? 【发布时间】:2013-04-13 06:03:57 【问题描述】:我正在用 Java 编写一个程序,它显示了一系列课后俱乐部(例如足球、曲棍球 - 由用户输入)。俱乐部添加到以下ArrayList
:
private ArrayList<Club> clubs = new ArrayList<Club>();
通过以下方法:
public void addClub(String clubName)
Club club = findClub(clubName);
if (club == null)
clubs.add(new Club(clubName));
'Club' 是一个带有构造函数的类 - 名称:
public class Club
private String name;
public Club(String name)
this.name = name;
//There are more methods in my program but don't affect my query..
我的程序正在运行 - 它让我可以在我的数组列表中添加一个新的俱乐部对象,我可以查看数组列表,我可以删除我想要的任何内容等。
但是,我现在想将该 arrayList (clubs) 保存到一个文件中,然后我希望能够稍后加载该文件并且相同的 arraylist 再次存在。
对此我有两种方法(见下文),并且一直在努力让它工作,但没有任何运气,任何帮助或建议将不胜感激。
保存方法(文件名由用户选择)
public void save(String fileName) throws FileNotFoundException
String tmp = clubs.toString();
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
pw.write(tmp);
pw.close();
加载方法(当前代码不会运行 - 文件是字符串但需要是俱乐部?
public void load(String fileName) throws FileNotFoundException
FileInputStream fileIn = new FileInputStream(fileName);
Scanner scan = new Scanner(fileIn);
String loadedClubs = scan.next();
clubs.add(loadedClubs);
我还使用 GUI 来运行应用程序,此时,我可以单击“保存”按钮,然后我可以输入名称和位置并保存它。该文件出现并可以在记事本中打开,但显示为 Club@c5d8jdj(对于我列表中的每个俱乐部)
【问题讨论】:
您看到的Club@c5d8jdj
是Object 类的toString()
方法的结果。您希望如何将列表保存在文件中?什么格式?
toString() 不适合写入文件。你想要序列化。
如果你想这样做,你必须重写 Club() 类的 toString() 方法,以便它包含所有信息,然后是一个构造函数,它能够重新创建目的。或者看看 Serializable 接口和 ObjectStreams:docs.oracle.com/javase/tutorial/essential/io/objectstreams.html
我没有偏好保存它的文件格式,只要它可以稍后在应用程序上加载..
【参考方案1】:
您应该使用 Java 的内置序列化机制。 要使用它,您需要执行以下操作:
将Club
类声明为实现Serializable
:
public class Club implements Serializable
...
这告诉 JVM 类可以序列化为流。您不必实现任何方法,因为这是一个标记接口。
要将您的列表写入文件,请执行以下操作:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(clubs);
oos.close();
要从文件中读取列表,请执行以下操作:
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
List<Club> clubs = (List<Club>) ois.readObject();
ois.close();
【讨论】:
如果您遇到“只读文件系统”异常,您可以将"t.tmp"
更改为file
,其中File file = new File(getFilesDir(), "t.tmp");
或File file = new File(getExternalFilesDir(null), "t.tmp");
但后者可能需要WRITE_EXTERNAL_STORAGE
许可。
我想将更多项目添加到 arraylist 包含文件中,我该怎么做? thnx 你的答案很有效【参考方案2】:
作为练习,我建议执行以下操作:
public void save(String fileName) throws FileNotFoundException
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club.getName());
pw.close();
这会将每个俱乐部的名称写在文件的新行中。
Soccer Chess Football Volleyball ...
我会把负载留给你。 提示:你一次写一行,然后你可以一次读一行。
Java 中的每个类都扩展了Object
类。因此,您可以覆盖其方法。在这种情况下,您应该对toString()
方法感兴趣。在您的 Club
课程中,您可以覆盖它,以您想要的任何格式打印有关该课程的一些消息。
public String toString()
return "Club:" + name;
然后您可以将上面的代码更改为:
public void save(String fileName) throws FileNotFoundException
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club); // call toString() on club, like club.toString()
pw.close();
【讨论】:
对于一个小数据集,这似乎还可以,但我非常怀疑它在给定一个庞大的数据集的情况下是否有效。【参考方案3】:在 Java 8 中,您可以使用带有两个参数的 Files.write() 方法:Path
和 List<String>
,如下所示:
List<String> clubNames = clubs.stream()
.map(Club::getName)
.collect(Collectors.toList())
try
Files.write(Paths.get(fileName), clubNames);
catch (IOException e)
log.error("Unable to write out names", e);
【讨论】:
【参考方案4】:这可能对你有用
public void save(String fileName) throws FileNotFoundException
FileOutputStream fout= new FileOutputStream (fileName);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(clubs);
fout.close();
回读你可以有
public void read(String fileName) throws FileNotFoundException
FileInputStream fin= new FileInputStream (fileName);
ObjectInputStream ois = new ObjectInputStream(fin);
clubs= (ArrayList<Clubs>)ois.readObject();
fin.close();
【讨论】:
【参考方案5】:ObjectOutputStream.writeObject(clubs)
ObjectInputStream.readObject();
此外,您的“添加”逻辑在逻辑上等同于使用 Set 而不是 List。列表可以有重复项,而集合则不能。你应该考虑使用一套。毕竟,你真的可以在同一所学校拥有2个国际象棋俱乐部吗?
【讨论】:
【参考方案6】:保存和加载一个数组列表 public static ArrayList data = new ArrayList ();
我曾经(写)...
static void saveDatabase()
try
FileOutputStream fos = new FileOutputStream("mydb.fil");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(data);
oos.close();
databaseIsSaved = true;
catch (IOException e)
e.printStackTrace();
// End of saveDatabase
并用于(阅读)...
static void loadDatabase()
try
FileInputStream fis = new FileInputStream("mydb.fil");
ObjectInputStream ois = new ObjectInputStream(fis);
data = (ArrayList<User>)ois.readObject();
ois.close();
catch (IOException e)
System.out.println("***catch ERROR***");
e.printStackTrace();
catch (ClassNotFoundException e)
System.out.println("***catch ERROR***");
e.printStackTrace();
// End of loadDatabase
【讨论】:
以上是关于Java - 如何将我的 ArrayList 写入文件,并将该文件读取(加载)到原始 ArrayList?的主要内容,如果未能解决你的问题,请参考以下文章