Repeated Writing and Loading ArrayList of objects from a file - java

I have a 'Person' class where i stored data like name, surname etc. I make 5 object type Person, add them to ArrayList, and save this ArrayList to file. Next i'm loading from this file ArrayList and i have 5 person. Problem is when i want save again for example 10 object Person. When i'm loading ArrayList from file i'm getting only 5 person from first writing. If i repeat this still i will have load data from first writing to this file. How i can fix this ?
public class Data {
static List<Person> persons = new ArrayList<Person>();
public static void main(String[] args) throws IOException {
Data.savePersons(5);
Data.loadPersons();
/** Clean 'persons' array for TEST of load data */
persons.removeAll(persons);
System.out.println("\n-----------\nNext Round\n-----------\n");
Data.savePersons(10);
Data.loadPersons();
}
/** Save a couple of Person Object to file C:/data.ser */
public static void savePersons(int noOfPersonToSave) throws IOException {
FileOutputStream fout = null;
ObjectOutputStream oos = null;
/** Make 5 'Person' object and add them to ArrayList 'persons' for example */
for (int i = 0; i < noOfPersonToSave; i++) {
Person personTest = new Person("name" + i, "surname" + i, "email" +i, "1234567890" +i);
persons.add(personTest);
}
try {
fout = new FileOutputStream("C:\\data.ser", true);
oos = new ObjectOutputStream(fout);
oos.writeObject(persons);
System.out.println("Saving '" + persons.size() + "' Object to Array");
System.out.println("persons.size() = " + persons.size());
System.out.println("savePersons() = OK");
} catch (Exception ex) {
System.out.println("Saving ERROR: " + ex.getMessage());
} finally {
if (oos != null) {
oos.close();
}
}
}
/** Load previously saved a couple of Person Object in file C:/data.ser */
public static void loadPersons() throws IOException {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream("C:\\data.ser");
ois = new ObjectInputStream(fis);
persons = (List<Person>) ois.readObject();
//persons.add(result);
System.out.println("-------------------------");
System.out.println("Loading '" + persons.size() + "' Object from Array");
System.out.println("persons.size() = " + persons.size());
System.out.println("loadPersons() = OK");
} catch (Exception e) {
System.out.println("-------------------------");
System.out.println("Loading ERROR: " + e.getMessage());
} finally {
if (ois != null) {
ois.close();
}
}
}}
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String surname;
private String mail;
private String telephone;
public Person(String n, String s, String m, String t) {
name = n;
surname = s;
mail = m;
telephone = t;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public String getMail() {
return mail;
}
public String getTelephone() {
return telephone;
}}

new FileOutputStream("C:\\data.ser", true)
You're passing true for the append parameter. So you're appending a list of 10 persons to the file, after the already existing list of 5 people. And since you only read one list, you read the first you wrote, which contains 5 persons.
Pass false instead of true.

Related

How can I format the different sections of the input .txt in Java

I need to format the I/O text, which comes from a .txt file. I am able to print it, but I can't separate it in the different categories.
public class Main {
public static void main(String[] args) throws Exception {
class Recipe implements java.io.Serializable {
private String name, ingredients, steps;
public Recipe(String name, String ingredients, String steps) {
this.name = name;
this.ingredients = ingredients;
this.steps = steps;
}
public String toString(){
return "dishName: " + name + " ingredients: " + ingredients + " steps: ";
}
}
Scanner input = null;
try {
//Choose the file that you will use.
input = new Scanner (new BufferedReader(new FileReader ("Root/src/recipes.txt")));
while ( input.hasNext() ) {
System.out.println(input.nextLine());
}
//Read your input and create the Objects Recipe
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null){
input.close();
}
} finally {
if (input != null){
input.close();
}
}
}
}
}

ObjectInput/OutputStream seems to not serialize/Deserialize

I'm writing a fairly simple program, which needs to save some simple data between runs. This data is defined by UserData, outlined below:
public class UserData implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3542558265070011448L;
public static ArrayList<String> projectList;
public static ArrayList<Bill> billList;
public static String userName;
public static String userEmail;
public UserData() {
}
public UserData(String name, String email) {
super();
userName = name;
userEmail = email;
projectList = new ArrayList<String>();
billList = new ArrayList<Bill>();
}
public String getUserName() {
return userName;
}
public String getUserEmail() {
return userEmail;
}
public ArrayList<Bill> getBillList() {
return billList;
}
public ArrayList<String> getProjectList() {
return projectList;
}
public void setBillList(Bill theBill) {
billList.add(theBill);
}
public void setProjectList(String projectName) {
projectList.add(projectName);
}
}
I Then have a class which handles serializing/deserializing of this data and it's instance to a file, with the various calls done directly or indirectly by events in a separate Gui Class. This is it:
public class FileHandler implements Serializable {
/**
*
*/
private static final long serialVersionUID = 473118590700911358L;
private static JFileChooser fileChooser;
public UserData myUserData;
public FileHandler() throws ClassNotFoundException, IOException {
fileChooser = new JFileChooser();
initData();
}
public FileHandler(UserData newUser) {
fileChooser = new JFileChooser();
myUserData = newUser;
System.out.println("Entered User: " + myUserData.getUserName());
System.out.println("Entered User: " + myUserData.getUserEmail());
}
private void createProgramData() throws FileNotFoundException, IOException {
FileOutputStream fileOut = new FileOutputStream("data\\ProgramData.diy");
ObjectOutputStream encoderp = new ObjectOutputStream(fileOut);
System.out.println("createProgramData: " + myUserData.getUserName());
System.out.println("createProgramData: "+ myUserData.getUserEmail());
encoderp.writeObject(myUserData);
encoderp.close();
fileOut.close();
}
public void exportData() throws FileNotFoundException, IOException {
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
final int selectedFile = fileChooser.showOpenDialog(null);
ObjectOutputStream encodere = null;
if (selectedFile == JFileChooser.APPROVE_OPTION) {
final File selectedPath = fileChooser.getSelectedFile();
FileOutputStream fileOut = new FileOutputStream(selectedPath + "\\UserData.diy");
encodere = new ObjectOutputStream(fileOut);
System.out.println("Writing Data: " + myUserData.getUserName());
System.out.println("Writing Data: " + myUserData.getUserEmail());
encodere.writeObject(myUserData);
encodere.close();
fileOut.close();
}
}
public void importData() throws ClassNotFoundException, IOException {
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
final int selectedFile = fileChooser.showSaveDialog(null);
ObjectInputStream decoderim = null;
if (selectedFile == JFileChooser.APPROVE_OPTION) {
final File selectedPath = fileChooser.getSelectedFile();
FileInputStream fileIn = new FileInputStream(selectedPath);
decoderim = new ObjectInputStream(fileIn);
myUserData = (UserData)decoderim.readObject();
decoderim.close();
fileIn.close();
System.out.println("importing Data: " + myUserData.getUserEmail());
System.out.println("importing Data: " + myUserData.getUserName());
}
}
private void initData() throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("data\\ProgramData.diy");
ObjectInputStream decoderi = new ObjectInputStream(fileIn);
myUserData = (UserData)decoderi.readObject();
decoderi.close();
fileIn.close();
System.out.println("initializing Data: " + myUserData.getUserName());
System.out.println("Initializing Data: " + myUserData.getUserEmail());
}
public UserData getUserData() {
return myUserData;
}
A problem I'm having with the ObjectInputStream and possibly ObjectOutputStream seems to be that when I serialize UserData, exit my program, and then re-enter and try to import that file, the instance of UserData remains unchanged. I can't seem to figure out what I'm missing. Even pointing out something I've overlooked helps.
UserData only has static fields, and static fields aren't serialized. From the look of your code they should all be instance members. Don't make anything static unless you know exactly why you are doing so.

read serializable custom object into file android

i am trying to record and reab back my list into file. It's working great until I restart my application. I am working with simulator (I don't have a real phone under Android)
Here is my function to record my class into a file :
public boolean writeRecordsToFile(String path, DummyContent object){
FileOutputStream fos;
ObjectOutputStream oos = null;
try {
fos = fileContext.openFileOutput(path, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.close();
Log.d("fileManager", "Records write successfully");
return true;
} catch (Exception e) {
Log.e("fileManager", "Cant save records : " + e.getMessage());
return false;
}
finally {
if (oos != null)
try {
oos.close();
} catch (Exception e) {
Log.e("fileManager", "Error while closing stream "+e.getMessage());
}
}
}
Here is my reading Function :
public boolean readRecordsFromFile(String path){
FileInputStream fin;
ObjectInputStream ois=null;
try {
fin = fileContext.openFileInput(path);
ois = new ObjectInputStream(fin);
DummyContent records = (DummyContent) ois.readObject();
records.addItem("test", "test", "test");
ois.close();
Log.d("fileManager", "Records read successfully :\n" + records.toString());
Log.d("fileManager", "nbArticle found : " + String.valueOf(records.ITEMS.size()));
Log.d("fileManager", "article 0 title :\n" + records.ITEMS.get(0).content);
Log.d("fileManager", "article 10 title :\n" + records.ITEMS.get(10).content);
return true;
} catch (Exception e) {
Log.e("fileManager", "Cant read saved records : "+e.getMessage());
return false;
}
finally {
if (ois != null)
try {
ois.close();
} catch (Exception e) {
Log.e("fileManager", "Error in closing stream while reading records : "+e.getMessage());
}
}
}
and here is my class :
public class DummyContent implements Serializable {
/**
* An array of sample (dummy) items.
*/
public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
/**
* A map of sample (dummy) items, by ID.
*/
public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
public void addItem(String first, String second, String third) {
DummyItem dummyItem = new DummyItem(first, second, third, android.R.drawable.ic_input_add);
ITEMS.add(dummyItem);
ITEM_MAP.put(dummyItem.id, dummyItem);
}
public void deleteAll() {
ITEMS = new ArrayList<DummyItem>();
ITEM_MAP = new HashMap<String, DummyItem>();
}
public void changeURL(Long index, String newURL) {
ITEMS.get(index.intValue()).url = newURL;
}
public void changeContent(Long index, String newContent) {
ITEMS.get(index.intValue()).contenu = newContent;
}
/**
* A dummy item representing a piece of content.
*/
public static class DummyItem {
public final String id;
public final String content;
public final String details;
public final int imageResource;
public String url;
public String contenu;
public DummyItem(String id, String content, String details, int imageResource) {
this.id = id;
this.content = content;
this.details = details;
this.imageResource = imageResource;
this.url = "";
this.contenu = "";
}
#Override
public String toString() {
return content;
}
}
}
Finally I read my file at the onCreate of my MainActivity (first activity at the lunching app) :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fileManager = new FileManager(this.getApplicationContext());
Log.d("Main", String.valueOf(fileManager.fileExist("Article.art")));
fileManager.readRecordsFromFile("Article.art"); /* Bug here : size of my array is empty but file's size is the same */
}
Here is my console return :
D/fileManager: size = 102
D/fileManager: Records read successfully :
D/fileManager: nbArticle found : 1 (because i add an item at the read
function) E/fileManager: Cant read saved records : Index: 10, Size: 1
I know it is working because when I write and read directly after the writting, I got all my items and I can read several times and I still got all items (this bug semms to be only present when I restart my application)
Maybe can I got help ?
Thanks !
The reason is very easy: You have declared some field as static, which are not covered by standard serialization: So, the contents of these fields were never written nor read from the file. That's why they "dissapeared" after a JVM restart.
Any field you want to be serialized/deserialized, you must declare it as instance member (not static).
See documentation on Serializable.

Print arraylist to text file in HUMAN READABLE form

so i can't figure out how to print an arraylist index (the first index so 0) to a text file. Basically, I have a Job class which stores 5 variables
public class Job {
public int teamNo;
public String regNo;
public String gridRef;
public String gridCopy;
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
and then I have an arraylist of type Job:
private static ArrayList<Job> teamNoOne = new ArrayList<Job>();
So the data all gets added fine, prints it out etc but I can't save it to a text file. this is my code, I just get the random hash code of it but I need it in human readable form.
try {
File file = new File("JOBS-DONE-LOG.txt");
FileOutputStream fs = new FileOutputStream(file);
ObjectOutputStream os = new ObjectOutputStream(fs);
System.out.println(teamNoOne.get(0));
os.writeObject(teamNoOne.get(0));
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
Can't figure out how to do it.
writeObject serializes the object in your file, it doesn't write it in textual form (http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeObject(java.lang.Object))
You must do it in another way: for example, you can use the BufferedWriter class and the write method to write the output of your toString() method.
Here is a complete example:
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
public class Job {
public String regNo;
public String gridRef;
public String gridCopy;
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
public static void main(String[] args) throws Exception {
ArrayList<Job> teamNoOne = new ArrayList<Job>();
// fill your array
Job job = new Job();
job.regNo = "123";
// continue to fill the jobs...
teamNoOne.add(job);
BufferedWriter writer = new BufferedWriter(new FileWriter("JOBS-DONE-LOG.txt"));
System.out.println(teamNoOne.get(0));
writer.write(teamNoOne.get(0).toString());
os.close();
}
}
Since you are trying to save an arraylist of type Job, it has to be serialized (Refer this).
public class Job implements java.io.Serializable
{
public int teamNo=0;
public String regNo="default";
public String gridRef="default";
public String gridCopy="default";
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
}
For Saving the file
try
{
FileOutputStream fileOut = new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(teamNoOne);
out.close();
fileOut.close();
}
catch(IOException i)
{
i.printStackTrace();
}
Thus you can load the arraylist back like
Object o = null;
try
{
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
o = in.readObject();
in.close();
fileIn.close();
}
catch(IOException i)
{
i.printStackTrace();
}
catch(ClassNotFoundException c)
{
c.printStackTrace();
}
Arraylist<Job> loaded_Job = (ArrayList<Job>) o;
Then print the arraylist
for(int i = 0; i < loaded_Job.size(); i++) {
loaded_Job.get(i).toString();
}
This happens because you didn't parameterize your ArrayList. Use generics when declaring your list:
ArrayList<Job> teamNoOne = new ArrayList<Job>();
Because now, though you have overriden your toString() method, teamNoOne.get(0) uses an Object's toString().

Java warning and error (read object)

My goal: save one ArrayList to a .dat file, after read this file and in the end print this array.
To save the ArrayList, "equipas" is one ArrayList< Equipa>, I use this function:
saveMyFile("Equipas.dat", (Object) equipas);
To read:
public static ArrayList<Equipa> readMyFile(String s){
ArrayList<Equipa> novo = new ArrayList<Equipa>();
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s));
novo = (ArrayList<Equipa>) ois.readObject();
ois.close();
}
catch(IOException er) { System.out.println(er.getMessage()); }
catch(ClassNotFoundException er) { System.out.println(er.getMessage()); }
return novo;}
In this read function, I have one Compilation Warning: "…uses unchecked or unsafe operations. Recompile with - Xlint:unchecked for details."
To save:
public static void saveMyFile(String s, Object o)
{
try {
ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(s));
oos.writeObject(o);
oos.flush();
oos.close();
}
catch(IOException e) { System.out.println(e.getMessage()); }
}
Finally, I want to print the ArrayList's info:
ArrayList<Equipa> cena = new ArrayList<Equipa>();
cena=(ArrayList<Equipa>) readMyFile("Equipas.dat");
for(Equipa e:cena)
e.toString();
Error when I try to run:
" writing aborted; java.io.NotSerializableException: Equipa"
Equipa havs the Serializable:
import java.util.*;
import java.io.*;
public class Equipa implements Serializable
{
private String nome;
private Carro carro;
private ArrayList<Piloto> pilotos;
private double tempoDecorrido;
private int pontos;
private boolean desistiu;
private int voltaDesistencia;
private Piloto piloto;
/**
* Constructor for objects of class Equipa
*/
public Equipa()
{
this.nome = "NA";
this.carro = null;
this.pilotos = new ArrayList<Piloto>();
this.tempoDecorrido = 0;
this.pontos = 0;
this.desistiu = false;
this.voltaDesistencia = 0;
this.piloto = null;
}
public Equipa(String nome, Carro carro, ArrayList<Piloto> pilotos)
{
this.nome = nome;
this.carro = carro;
//this.pilotos = new ArrayList<Piloto>(pilotos);
this.pilotos = pilotos;
this.tempoDecorrido = 0;
this.pontos = 0;
this.desistiu = false;
this.voltaDesistencia = 0;
//this.piloto = pilotos.get(0);
}
public Equipa (Equipa e)
{
this.nome = e.getNome();
this.carro = e.getCarro();
this.pilotos = e.getPilotos();
this.tempoDecorrido = e.getTempoDecorrido();
this.pontos = e.getPontos();
this.desistiu = e.getDesistiu();
this.voltaDesistencia = e.getVoltaDesistencia();
//this.piloto = e.getPiloto();
}
/** Getters */
public String getNome()
{
return this.nome;
}
public Carro getCarro()
{
return this.carro;
}
public ArrayList<Piloto> getPilotos()
{
return new ArrayList<Piloto>(this.pilotos);
}
public double getTempoDecorrido()
{
return this.tempoDecorrido;
}
public int getPontos()
{
return this.pontos;
}
public boolean getDesistiu()
{
return this.desistiu;
}
public int getVoltaDesistencia()
{
return this.voltaDesistencia;
}
public Piloto getPiloto()
{
return this.piloto;
}
/** Setters */
public void setNome(String nome)
{
this.nome = nome;
}
public void setCarro(Carro carro)
{
this.carro = carro;
}
public void setPilotos(ArrayList<Piloto> pilotos)
{
this.pilotos = new ArrayList<Piloto>(pilotos);
}
public void setTempoDecorrido(double tempoDecorrido)
{
this.tempoDecorrido = tempoDecorrido;
}
public void setPontos(int pontos)
{
this.pontos = pontos;
}
public void setDesistiu(boolean desistiu)
{
this.desistiu = desistiu;
}
public void setVoltaDesistencia(int voltaDesistencia)
{
this.voltaDesistencia = voltaDesistencia;
}
public void setPiloto(Piloto piloto)
{
this.piloto = piloto;
}
/** Outros Métodos */
public Equipa clone()
{
return new Equipa(this);
}
public boolean equals(Equipa e)
{
if(this.nome == e.getNome())
return true;
else
return false;
}
public String getStringPilotos()
{
String s = new String();
for(Piloto p: this.pilotos)
s = (s + ", " + p.getNome());
return s;
}
public String toString()
{
return new String("Nome da equipa: " + nome + "; Categoria do carro: " + carro.getClass().getName() + "; Marca e modelo: " + carro.getMarca() + " " + carro.getModelo() + "; Pilotos: " + getStringPilotos())+"\n";
}
Implementing Serializable means that serialization is permitted, but not necessarily that it is possible. For it to work, everything referenced by Equipa must also be either primitive or Serializable (and so on, recursively). Is this the case?
Warning in the read function is the result of generics in java. You won't be able to suppress it, unless you use #SuppressWarnings("unchecked") to ignore it.
If you are sure you are reading an ArrayList<Equipa>, you can ignore it without any problem.
With the Equipa code, I can try to point to the Serializable problem: make sure that Carro and Piloto classes are also Serializables. You can add the code of theses classes if you are not sure.
The only type-safer way would be do a custom serialization, using writeObject(OutputStream) and readObjectInputStream say on a class ArrayListOfEquipa maybe using Equipa[] (ArrayList.toArray()).
Not really attractive, if the warning would be the only reason.

Categories