【问题标题】:FileInputStream & FileOutputStream文件输入流和文件输出流
【发布时间】:2017-03-31 16:21:49
【问题描述】:

我正在尝试将 Java 应用程序中的对象保存到文件中,以便在应用程序关闭后使用。我了解您使用 FileInputStream/ObjectInputStream 从文件中读取对象并使用 FileOutputStream/ObjectOutputStream 将对象写入文件。到目前为止,我能够成功地将对象保存到文件中,并在我重新打开应用程序时将它们重新加载到应用程序中。然而我的问题是这只能工作一次。

我启动应用程序,输入数据并关闭应用程序。数据被写入指定的文件,当我重新打开应用程序时,数据会正确地重新加载到应用程序中,但是如果我添加任何新数据,它不会在应用程序关闭时写入指定的文件。然后,当我第二次重新打开应用程序时,没有数据被读入应用程序,使应用程序完全空白。

这是我编写对象的代码:

static class quit_Action implements ActionListener
{
    @Override
    public void actionPerformed (ActionEvent e)
    {
        try
        {
            FileOutputStream savedData = new FileOutputStream("groupData.txt", false);
            ObjectOutputStream save = new ObjectOutputStream(savedData);
            save.writeObject(existingGroups);
            save.writeObject(groupCombo);
            save.writeObject(groupList);
            System.out.println("Data Saved");
            save.close();
            System.out.println("savedData Closed");

        }
        catch(IOException ioe)
        {
        }
        System.exit(0);
    }
}

第一次运行时,系统输出“Data Saved”和“savedData Closed”,但第二次运行时没有打印任何打印语句。通过故障排除,我已经确定了所有代码到

ObjectOutputStream save = new ObjectOutputStream(savedData);

运行,但之后的任何行都不会出现,除了系统退出。

这是我的对象读取代码:

try
    {
        FileInputStream loadedData = new FileInputStream("groupData.txt");
        ObjectInputStream load = new ObjectInputStream(loadedData);
        existingGroups = (ArrayList<NewGroup>) load.readObject();
        groupCombo = (DefaultComboBoxModel) load.readObject();
        groupList = (DefaultListModel) load.readObject();
        System.out.println("Data Loaded");
        loadedData.close();
        System.out.println("loadedData Closed");   
    }
    catch(IOException ioe2)
    {
    }

这与写入部分存在相同的问题,即第一次打印“Data Loaded”和“loadedData Closed”,但不是第二次。代码到

ObjectInputStream load = new ObjectInputStream(loadedData);

运行,但在 try 语句中没有任何内容。

如果我删除文件 groupData.txt 并重新打开应用程序,我可以再次读取和写入,但只能读取一次。我曾尝试使用 File.delete() 方法删除应用程序中的文件,但即使应用程序通过这行代码,文件也不会自行删除。我的想法是我可以删除该文件,然后直接创建一个新的同名文件,然后在关闭程序之前将对象写入新文件。这没有奏效。每次使用

创建 FileOutPutStream 时,我也尝试创建一个新文件
FileOutputStream out = new FileOutputStream(new File(groupData.txt), false);

但这也没有用。

我想也许我可以想出一种方法,在每次打开应用程序时创建一个具有不同名称的文件,并使用它来创建我的流,但我不知道该怎么做,而且它也会变得混乱无论文件是在哪个目录中创建的,都有一堆无用的文件。

这就是我的对象的初始化方式

static DefaultListModel groupList = new DefaultListModel();
static DefaultComboBoxModel groupCombo = new DefaultComboBoxModel();
static ArrayList<NewGroup> existingGroups = new ArrayList<NewGroup>();

我在网上查看,但大多只能找到关于如何在应用程序中写入/读取对象的教程,我已经知道如何去做(虽然只有一次),这就是为什么我想我会问求助。如果已经问过这个问题,我深表歉意,我查看了十几个问题,但它们与这个特定问题无关。

【问题讨论】:

  • 您是否尝试打印 IOException?
  • 默默吞下异常是一个重大错误。永远不要那样做。
  • 当我尝试打印堆栈跟踪并说删除它时,我的 IDE 给了我一个警告,这就是我没有打印它们的原因
  • 好的,我添加了打印堆栈跟踪并获取 java.io.NotSerializableException: com.apple.laf.AquaPainter$AquaSingleImagePainter 我知道这意味着它是序列化的问题,但为什么它会首先起作用时间而不是第二次?
  • 这些对象是否实现Serializable

标签: java fileinputstream fileoutputstream objectinputstream objectoutputstream


【解决方案1】:

使用FileOutputStream savedData = new FileOutputStream("groupData.txt", ***true***); 代替FileOutputStream savedData = new FileOutputStream("groupData.txt", ***false***);。第二个参数设置为 true 时,表示您要向文件中添加数据。当您选择“false”时,现有数据会在保存新数据之前被删除。

【讨论】:

  • 我这样做是因为我想用更新版本替换文件中的对象,而不是在文件末尾添加另一个副本。我只想要每个对象的一个​​版本。我也试过这个,但仍然遇到同样的问题。
  • 好的。使用FileOutputStream,您必须读取已保存在文件中的所有对象并将它们保存回文件,仅替换您要更改的对象。工作,但可能会很耗时,因为你有很多对象。如果您有很多对象,则使用 SQL 数据库或SharedPreferencesfile(如果只需要几个对象)会更好、更高效,但会以更复杂的保存过程为代价。
【解决方案2】:

我参加聚会有点晚了,但为了将来的参考可能......

您打开savedDatasave 流,但只打开close() 后者。 FileOutputStream 保持打开状态并阻止您再次写入该文件的尝试。

故事的士气:始终使用try-with-resources

【讨论】:

    猜你喜欢
    • 2012-05-16
    • 2021-11-19
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2012-05-02
    相关资源
    最近更新 更多