I'm a beginner with Java and I meet a problem with a read/write to text file.
The process :
- read and display the text file : System.out.println(garage);
- add a first car : garage.addVoiture(lag1);
- add a second car : garage.addVoiture(A300B_2);
Here is main.java :
import fr.ocr.vehicule2.*;
public class Main {
public static void main(String[] args) {
Garage garage = new Garage();
System.out.println(garage);
Vehicule lag1 = new Lagouna();
lag1.setMoteur(new MoteurEssence("150 Chevaux", 10256d));
lag1.addOption(new GPS());
lag1.addOption(new SiegeChauffant());
lag1.addOption(new VitreElectrique());
garage.addVoiture(lag1);
Vehicule A300B_2 = new A300B();
A300B_2.setMoteur(new MoteurElectrique("1500 W", 1234d));
A300B_2.addOption(new Climatisation());
A300B_2.addOption(new BarreDeToit());
A300B_2.addOption(new SiegeChauffant());
garage.addVoiture(A300B_2);
}
and here is garage.java
package fr.ocr.vehicule2;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class Garage {
private List<Vehicule> voitures = new ArrayList<Vehicule>();;
ObjectInputStream ois;
ObjectOutputStream oos;
public Garage(){
}
public String toString() {
System.out.println("DEBUG start toString");
String str = "";
// Vérification de l'existence du fichier de sauvegarde
if(Files.notExists(Paths.get("garage.txt"))) str += "Aucune voiture sauvegardée !\n";
str += "*************************\n"
+ "* Garage OpenClassrooms *\n"
+ "*************************\n";
// Lecture du fichier texte
if(Files.exists(Paths.get("garage.txt"))) {
try {
ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File("garage.txt"))));
str += ((Vehicule)ois.readObject()).toString();
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (EOFException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("DEBUG end toString");
return str;
}
public void addVoiture(Vehicule voit) {
System.out.println("DEBUG start addVoiture" + voit);
voitures.add(voit);
// écriture du fichier texte
try {
oos = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(
new File("garage.txt"))));
// for(Vehicule V:voitures){
// oos.writeObject(V);
// }
oos.writeObject(voit);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("DEBUG end addVoiture");
}
}
First execution of main.java, (the text file doesn't exists) I get in console :
- Aucune voiture sauvegardée !
- Garage OpenClassrooms *
- start addVoiture
- end addVoiture
- start addVoiture
- end addVoiture
That's what I want to show in console for first launch.
But second execution of main.java, (the text file exists), I get in console :
- DEBUG start toString
- DEBUG end toString
- Garage OpenClassrooms *
- Voiture PIGEOT : Lagouna Moteur ELECTRIQUE 1500 W (1234.0) [Climatisation (347.3€), Barre de toit (29.9€), Siège chauffant (562.9€)] d'une valeur totale de 2174.1€
- DEBUG start addVoiture+ Voiture RENO : Lagouna Moteur ESSENCE 150 Chevaux (10256.0) [GPS (113.5€), Siège chauffant (562.9€), Vitres electrique (212.35€)] d'une valeur totale de 11144.75€
- DEBUG end addVoiture
- DEBUG start addVoiture+ Voiture PIGEOT : Lagouna Moteur ELECTRIQUE 1500 W (1234.0) [Climatisation (347.3€), Barre de toit (29.9€), Siège chauffant (562.9€)] d'une valeur totale de 2174.1€
- DEBUG end addVoiture Only the second car (+ Voiture PIGEOT) is shown in console.
The result I want is both of them, ordered the same way I added them :
_ * Garage OpenClassrooms * _ *************************- Voiture RENO : Lagouna Moteur ESSENCE 150 Chevaux (10256.0) [GPS (113.5€), Siège chauffant (562.9€), Vitres electrique (212.35€)] d'une valeur totale de 11144.75€
- Voiture PIGEOT : Lagouna Moteur ELECTRIQUE 1500 W (1234.0) [Climatisation (347.3€), Barre de toit (29.9€), Siège chauffant (562.9€)] d'une valeur totale de 2174.1€
I don't find the solution to this issue, Is it because I don't write correctly both cars : oos.writeObject(voit); or because I don't read it correctly : str += ((Vehicule)ois.readObject()).toString(); ?
I've searched a lot even on stackoverflow but the code seems to be correct. So it may be a problem with the way I write then read the file ?
Thanks a lot if someone can help, I'm spending lots of time but turn around.
Added after @Kevin Anderson informations :
Thanks a lot again for help!
I changed readObject with your script but I still get only the last car added.
I've also seen this post (java.io.StreamCorruptedException: invalid type code: AC) and wasn't able to solve it. So I changed the way I writeObject (stopped appending objects to ObjectOutputStream) and get an almost good result.
Now my ultime issue is with "Type safety: Unchecked cast from Object to List" on readObject().
I think (not sure ?) that it's just an IDE information so I suppose it would be better to do the correct way, so I would like to avoid using (@SuppressWarnings("unchecked")) over (public String toString() {) and do it the best way but I was unable to apply any of all solutions I found on Stackoverflow.
If you have an idea, that would be really perfect !
Here is new garage.java :
public class Garage {
private List<Vehicule> voitures = new ArrayList<Vehicule>();
private ObjectInputStream ois;
protected static ObjectOutputStream oos;
public Garage(){}
public String toString() {
String str = "";
// Vérification de l'existence du fichier de sauvegarde
if(Files.notExists(Paths.get("garage.txt"))) {
str += "Aucune voiture sauvegardée !\n";
}
str += "*************************\n"
+ "* Garage OpenClassrooms *\n"
+ "*************************\n";
// Lecture du fichier texte
if(Files.exists(Paths.get("garage.txt"))) {
try {
ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File("garage.txt"))));
// garage loading during instanciation :
// Information Eclipse :
// Type safety: Unchecked cast from Object to List<Vehicule>
this.voitures = (List<Vehicule>)ois.readObject();
// Affichage des voitures enregistrées dans le fichier texte
for(Vehicule V : this.voitures){
str += V;
}
// To avoid "Type safety: Unchecked cast from Object to List<Vehicule>" :
// those 2 solutions show identical information "Type safety: Unchecked cast from Object to List<Vehicule>"
// First tried solution :
// this.voitures = new new ArrayList<Vehicule>((List<Vehicule>)ois.readObject());
// Second tried solution :
// if(ois.readObject() instanceof List<?>){
// List<?> list = (ArrayList<?>)ois.readObject();
// for(Object e : list){
// if(e instanceof Vehicule){
// this.voitures = (List<Vehicule>)e;
// }
// }
// }
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (EOFException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return str;
}
public void addVoiture(Vehicule voit) {
voitures.add(voit);
// écriture du fichier texte
try {
oos = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(
new File("garage.txt"))));
// Enregistrement detoutes les voitures dans le fichier texte
oos.writeObject(voitures);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Added solution for Type safety: Unchecked cast from Object to List
Thanks to this post : Type safety: Unchecked cast
The text file contains a List object and when I launch Garage() I needed to add this List object to the existing List voitures.
Eclipse was showing : Type safety: Unchecked cast from Object to List
I could use : @SuppressWarnings("unchecked") to my method, but it looks better to do this way so I don't ignore any warning :
List<?> list = (List<?>) ois.readObject();
for(int i = 0; i < list.size(); i++) {
this.voitures.add((Vehicule) list.get(i)); // instanciation
str += (Vehicule) list.get(i);// Added to console message
}
Hope it helps, sorry for my beginner mistakes ^^, and thanks to all for help !