Чтение и Запись Object Array List в файл

188
29 марта 2019, 15:00

Как реализовать запись объектного Array List в файл: txt или xml. Пожалуйста, разъясните это на конкретных примерах. Делаю курсовую по ООП на Java. Имеется следующий код:

package main;
import java.io.Serializable;
import java.util.Scanner;
public class User implements Serializable {
 private final String ANSI_BLUE = "\u001B[34m";
 Scanner in = new Scanner(System.in);
 private String Name;
 private String tel;
public String SetName(){
    System.out.print("Введите имя пользователя: "); //ADD NAME OF USER
    Name = in.nextLine();
    return Name;
}
public String SetTel(){
    System.out.print("Введите телефон пользователя: "); //ADD TEL OF USER
    tel = in.nextLine();
    return tel;
}
public String GetName(){
    return Name;
}
public String GetTel(){
   return tel; 
}
public void show_all(){
   System.out.println(ANSI_BLUE + "Пользователь:"); //USER
   System.out.println("Имя: " + GetName()); //NAME
   System.out.println("Телефон: " + GetTel()); //TELL
}
}

Класс User отвечает за создание самого объекта типа User.

    public class Users implements Serializable{
    public static final String ANSI_RED = "\u001B[31m";
    public static final String ANSI_RESET = "\u001B[0m";
    public static final String ANSI_GREEN = "\u001B[32m";
    public static final String ANSI_PURPLE = "\u001B[35m";
    ArrayList<User> users;
    private int count = 0; 
    public Users(ArrayList<User> users, int count){
        this.users = users;
        this.count = count;
    }    

    public void Add(){
        System.out.println();
        System.out.println(ANSI_GREEN + "Добавьте пользователя!" + ANSI_RESET );  //Add a User
        while(count  >= 0){
            User user = new User();
            user.SetName();
            user.SetTel();
           // System.out.println("Значение index: " + count);
            users.add(count, user);
            count++;
            System.out.println();
            break;
        }
    }   
    public void Show_All(){
        System.out.println();
        for (int i = 0; i < users.size(); i++) {
        users.get(i).show_all();
         System.out.println("ID: " + i);
         System.out.println();
         //System.out.println("Значение count: " + count);
        }
    }
    public void Remove_User(int i){
        users.get(i).show_all();
        System.out.println("ID: " + i);
        users.remove(i);
        count = count - 1;
        System.out.println(ANSI_PURPLE + "Удалён" + ANSI_RESET); //User Deleted
        System.out.println();
    }
    public void Save_Users() throws IOException{
        Users users = new Users();
        Serialization save = new Serialization();
        save.Save(users);
    } 
    public void main(String[] args) throws IOException {       
        Users users = new Users();
         int e = 1;       
        while (e != 0)
    {
        System.out.println(ANSI_RED + "Выберите комманду" + "\u001B[0m");
        System.out.println("1 - Добавить пользователя\n2 - Вывести всех пользователей\n3 - Удалить пользователя\n4 - Сохранить и выйти\n");
        System.out.print("Введенная команда: ");
        Scanner in = new Scanner(System.in);
        char y;
        y = in.next().charAt(0);
           switch(y)
            {
                case '1' :
                users.Add(); //users.Add();
                break;
                case '2' :
                users.Show_All();
                break;
                case '3' :
                System.out.println();
                System.out.print(ANSI_GREEN + "Введите ID пользователя: "  + ANSI_RESET);
                int i = in.nextInt();
                users.Remove_User(i);
                break;
                case '4' :
                System.out.print(ANSI_RED + "Сохранение данных " + ANSI_RESET);
                users.Save_Users();
                System.exit(0);
                break;
            }
        }    
    }  
}

В классе Users создаётся объектный ArrayList для User. Для дальнейшего динамического использования. Вывод через байтовый поток.

public class Serialization {
    public void Save(Users users) throws IOException{
        File file = new File("users.dat");
        ObjectOutputStream oos = null;
        FileOutputStream fos = new FileOutputStream(file);
        oos = new ObjectOutputStream(fos);
        oos.writeObject(users);
        oos.close();
    }
}

Проблема заключается в том, что после добавление конструктора.

public Users(ArrayList<User> users, int count){
        this.users = users;
        this.count = count;
    }  

Для создание экземпляра Users users = new Users(); (который мы потом записываем файл в методе SaveUser(), так же он используется в меню для вызова функций добавления, удаления и вывода всех пользователей) вылезает такая ошибка:

constructor Users in class Users cannot be applied to given types; required: ArrayList,int found: no arguments reason: actual and formal argument lists differ in length

Я не понимаю какие формальные параметры использовать.. для этого экземпляра. И будет ли потом программа правильно выполнять сериалилизацию моего списка с объектами User, а не сам пустой список.

Answer 1

Для того,чтобы записать класс Users со всеми его переменными экземпляра,вам нужно использовать сериализацию объекта. Сериализация - это как бы записанный(сжатый) объект.Вот представьте себе надувную фигуру. Вы можете спустить надувную фигуру и положить в коробку,например.А если бы вы этого не сделали,то надутая фигура вряд-ли поместиться в маленькую коробочку.

Спустить фигуру и положить в коробку - Сериализация

Вытянуть фигуру и надуть её - ДИсериализация

Как бы,можно сохранить данные объекта(состояние,переменные экземпляры) в txt и сделать конструктор,чтобы передавать построчно параметры для НОВОГО объекта.Но вам нужно другое. Именно "сдуть" объект и положить в файлик.Сделать это можно следующим образом :

Класс Объекта,который будут спускать(сериализовать) должен реализовать интерфейс Serializable

public class Users implements Serializable {
}

А теперь внимательно!

Для того,чтобы сериализовать объект со всеми его полями(переменными экземпляра) НУЖНО чтобы все его объектные ссылки тоже реализовали интерфейс Serializable

public class User implements Serializable{
}

Большинство классов за вас уже реализуют интерфейс Serializable,а некоторые не могут вообще.

Идем дальше :

Для того,чтобы записать объект Users в файл,нам нужно использовать потоки поток соединения - простой байтовый поток(FileInputStream(входящий) , FileOutputStream(исходящий).

И потоки,в которые мы будем впихать объекты,а там они будут сжиматься или надуваться : ObjectInputStream(входящий-надуваем) ObjectOutputStream(Исходящий-сдуваем).

Пример :

public void main(String[] args){
    try{
       //Записываем в файл объект Users(спускаем фигуру и запихиваем в коробку)
      Users users = new Users();
      FileOutputStream fos = new FileOutputStream("имя файла");    
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.close();//oos - это внешний поток.Если мы закрываем внешний то и 
      внутренний тоже.
      //Читаем с файла объект Users(достаем фигуру с коробки и надуваем)
      FileInputStream fis = new FileInputStrea("имя коробки");
      ObjectInputStream ois = new ObjectInputStream(fis);
      Object obj= ois.readObject();//Получаем объекты в том порядке,в котором 
      //записывали(Спустили фигуру собачки и положили в коробку первую,значит
      //и достаем тогда её первой и надуваем
      //Так как Object нужно привести к типу ниже в иерархии
      Users users = obj;
      ois.close();
    catch(IOException ex){
    ex.printStackTrace();
}catch(ClassNotFoundException ex){
 //Данное исключение может появиться,если класс объекта,
 //которые мы хотим надуть не найден.
    ex.printStackTrace();
}

В данном примере я записал в файл объект Users , который содержит ArrayList Ибо,если вы запишете только ArrayList users объект в файл,то какая от этого польза,Если у вашем классе Users нету конструктора или какого-то метода,чтобы принимал объект ArrayList users.

А все нужные вам методы находятся в классе Users. Чтобы был смысл записывать ArrayList нужно сделать следующее:

 public class Users {
    ArrayList<Users> users;
    public Users(ArrayList<Users> users){
        this.users = users;
    }
  }

Я думаю,суть вы уловили!Спасибо за внимание!

READ ALSO
Как избавиться от перезаписи файла?

Как избавиться от перезаписи файла?

Есть метод writeToFile, который записывает нужные данные в файлtxt, проблема в том что текст каждый раз перезаписывается, а мне нужно чтобы добавлялся

183
Не передаются данные JSP -&gt; Controller (Spring mvc)

Не передаются данные JSP -> Controller (Spring mvc)

Изучаю SpringПытаюсь создать форму регистрации

166
Привести Object к Cookie

Привести Object к Cookie

Столкнулся с такой проблемойВ БД записал объект класса Cookie вот таким вот образом :

244
Отслеживание схожесть символов Java

Отслеживание схожесть символов Java

Есть не тривиальная задачка отслеживать схожесть идентификаторов +- в %-ном соотношенииБольше надеюсь узнать нет ли какой то либы от гугла,...

173