FileInputStream и FileOutputStream

Я пытаюсь сохранить объекты из приложения 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);
    }
}

При первом запуске система выводит «Данные сохранены» и «Сохраненные данные закрыты», но при втором запуске оператор печати не печатается. Благодаря устранению неполадок я определил весь код до

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)
    {
    }

Это имеет ту же проблему, что и часть записи, в которой «Данные загружены» и «Загружены данные закрыты» печатаются в первый раз, но не во второй раз. Код до

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

Я искал в Интернете, но в основном я могу найти только учебники о том, как записывать/читать объекты в приложение и из него, что я понял, как это сделать (хотя и только один раз), поэтому я решил, что обращусь за помощью. Если это уже было задано, прошу прощения, я просмотрел около десятка вопросов, и они не относились к этой конкретной проблеме.


person Connor Ward    schedule 31.03.2017    source источник
comment
Вы пытались распечатать IOException?   -  person codemonkey    schedule 31.03.2017
comment
Глубоко проглатывать исключения — большая ошибка. Никогда не делай этого.   -  person Henry    schedule 31.03.2017
comment
Моя IDE выдает мне предупреждение, когда я пытаюсь распечатать трассировку стека, и говорит удалить ее, поэтому я их не распечатывал.   -  person Connor Ward    schedule 31.03.2017
comment
Хорошо, я добавил трассировку стека и получил java.io.NotSerializableException: com.apple.laf.AquaPainter$AquaSingleImagePainter. Я понимаю, что это означает проблему с сериализацией, но почему это сработает в первый раз, а не во второй?   -  person Connor Ward    schedule 31.03.2017
comment
Эти объекты реализуют Serializable?   -  person SantiBailors    schedule 31.03.2017


Ответы (2)


Вместо FileOutputStream savedData = new FileOutputStream("groupData.txt", ***false***); используйте FileOutputStream savedData = new FileOutputStream("groupData.txt", ***true***);. Второй параметр, если установлено значение true, указывает, что вы хотите добавить данные в свой файл. Поскольку вы выбрали «false», существующие данные стираются перед сохранением новых данных.

person Zelig63    schedule 31.03.2017
comment
Я сделал это, потому что хочу заменить объекты в файле обновленными версиями, а не добавлять в конец еще одну копию. Мне нужна только одна версия каждого объекта. Также я попробовал это, и у меня все еще есть та же проблема. - person Connor Ward; 31.03.2017
comment
ХОРОШО. С помощью FileOutputStream вы должны прочитать все объекты, уже сохраненные в файле, и сохранить их обратно в файл, заменив только тот, который вы хотите изменить. Работает, но может занять много времени, если у вас много объектов. Гораздо лучше и эффективнее использовать либо базу данных SQL, если у вас много объектов, либо SharedPreferencesfile, если необходимо всего несколько объектов, но за счет более сложного процесса сохранения. - person Zelig63; 01.04.2017

Я немного опоздал на вечеринку, но на будущее, может быть...

Вы открываете savedData и save потоки, но только close() последний. FileOutputStream останется открытым и снова заблокирует ваши попытки записи в этот файл.

Мораль истории: всегда используйте попробуйте-с-ресурсами.

person Imaskar    schedule 20.05.2018