저는 Java 초보자이고 텍스트 파일에 대한 읽기/쓰기 문제가 있습니다.직렬화 - readObject가 전체 파일을 읽지 않는 이유는 무엇입니까?
과정 :
- 읽기 및 텍스트 파일 표시 :에서 System.out.println (차고);
- 첫 번째 차량을 추가하십시오 : garage.addVoiture (lag1);
- 두 번째 차량 추가 : garage.addVoiture (A300B_2); 여기
가 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);
}
여기 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");
}
}
main.java의 첫 번째 실행, 난 수 (텍스트 파일이 존재하지 않습니다) 콘솔에서 :
- Aucune voiture sauvegardée!
-
-
- 차고 OpenClassrooms *
-
- 시작 addVoiture
- 최종 addVoiture
- 시작 addVoiture
- 최종 addVoiture
그게 내가 처음 출시 할 때 콘솔에 보여주고 싶은 내용입니다.
그러나 main.java의 두 번째 실행 (텍스트 파일이 존재), 내가 콘솔에서 얻을 :
- DEBUG 시작 toString
- DEBUG 끝 toString
-
-
- 주차장 OpenClassrooms *
- 0125178949 22,398,581,088,243,210
-
- Voiture PIGEOT : Lagouna MOTEUR ELECTRIQUE 1,500 W (1234.0)의 Climatisation (347.3 €) 바레 드 TOIT (29.9 €) 공성 chauffant (562.9 €)] 디 UNE valeur 토탈 데 2174.1 €
- DEBUG addVoiture + Voiture 리노를 시작 Lagouna MOTEUR 에센스 150 Chevaux (10256.0) GPS (113.5 €) 공성 chauffant (562.9 €)를 Vitres ELECTRIQUE (212.35 €)] 디 UNE valeur 토탈 데 11144.75 €
- DEBUG end addVoiture
- DEBUG 시작 addVoiture + Voiture PIGEOT : Lagouna Moteur ELECTRIQUE 1500 W (1234.0)) [Climatisation (347.3 €), Barre de toit (29.9 €), Siège chauffant (562.9 €)] 총액 2174.1 €
- DEBUG end addVoiture 두 번째 자동차 (+ Voiture PIGEOT) 만 콘솔에 표시됩니다.
내가 그들 모두, 내가 그들을 추가 같은 방식으로 정렬되어 원하는 결과 :
-
_ * 차고 OpenClassrooms * _ ***********을 ************** -
- Voiture RENO : Lagouna MOTEUR 에센스 150 Chevaux (10256.0) GPS (113.5 €) 공성 chauffant (562.9 €) Vitres ELECTRIQUE (212.35 €)] 총액 11144.75 € ,
-
- Voiture PIGEOT : Lagouna MOTEUR ELECTRIQUE 1,500 W (1234.0)의 Climatisation (347.3 €) 바레 드 TOIT (29.9 €) 공성 chauffant (562.9 €)] 디 UNE valeur 토탈 데 2174.1 € 내가 제대로 양쪽 차를 쓰지 않기 때문에
나는이 문제에 대한 해결책을 찾을 수없는, 그것을인가 : oos.writeObject (voit를); 또는 올바르게 읽지 않았기 때문에 str + = ((Vehicule) ois.readObject()). toString(); ?
stackoverflow에서도 많은 부분을 검색했지만 코드가 정확하다고 보입니다. 그래서 파일을 쓰는 방식에 문제가있을 수 있습니까?
누군가가 도울 수 있으면 고마워, 나는 많은 시간을 보내고 있지만 돌아 서.
추가 된 후 @Kevin 앤더슨 정보 : 도움을 다시
감사합니다 많이!
스크립트로 readObject를 변경했지만 여전히 마지막으로 추가 된 차량 만 얻습니다.
이 게시물 (java.io.StreamCorruptedException: invalid type code: AC)을 보았지만 해결할 수 없었습니다. 그래서 writeObject (ObjectOutputStream에 객체를 추가하는 것을 중단했습니다) 방식을 변경하고 거의 좋은 결과를 얻었습니다.
이제 나의 궁극적 인 문제는 readObject()의 "유형 안전 : 체크되지 않은 객체 간 변환"입니다.
내가 생각하기에 (확실하지 않습니까?) 단지 IDE 정보이므로 올바른 방법을 사용하는 것이 더 좋을 것이라고 생각합니다. 그래서 (public @ String (@SuppressWarnings ("unchecked")) toString() {) 그리고 그것을 최선의 방법으로하지만 Stackoverflow에서 찾은 모든 솔루션을 적용 할 수 없었습니다.
아이디어가 있다면 정말 완벽 할 것입니다.
새 차고입니다.자바 :
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();
}
}
}
유형의 안전을 위해
추가 솔루션 : 검사되지 않은이 게시물에
감사 목록에 Object에서 주연 : Type safety: Unchecked cast이
텍스트 파일이 목록 개체를 포함 Garage()를 실행하면이 List 객체를 기존 List voitures에 추가해야했습니다. 내 방법 ("선택 해제") @SuppressWarnings를하지만, 내가하지 않는이 방법을 수행하는 더 나은 외모 : 체크되지는
을 목록에 Object에서 캐스팅 내가 사용할 수 있습니다 유형 안전 :
이클립스 보여주는데 경고를 무시하십시오 :
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
}
희망, 내 초보자 실수로 인해 유감스럽게 생각합니다. ^^ 도움을 주신 모든 분들께 감사드립니다!
당신은'텍스트 파일이 존재합니다'를 쓰지 만'ObjectOutputStream'은 텍스트가 아닌 바이너리를 씁니다. – Kayaman