2 Stimmen

Serialisierung einer HashMap, aber die Textdatei für die Eingabe wird bei jedem Programmstart gelöscht. -- Java

Ich habe mir bereits andere Probleme angesehen, aber ich glaube nicht, dass eines davon zu meinem passt. Die Essenz meines Programms besteht darin, eine HashMap von Aktien zu erstellen (der Schlüssel ist das Kennzeichen und der Wert ist ein Stock-Objekt) und dann beim Beenden des Programms die HashMap in eine Textdatei zu exportieren. Das nächste Mal, wenn ich das Programm ausführe, würde ich die HashMap einlesen und das Programm fortsetzen. Bisher funktionieren alle meine anderen Funktionen und ich kann mir die Textdatei ansehen, nachdem ich das Programm ausgeführt habe, und ich sehe etwas Code darin, aber wenn ich das Programm erneut ausführe, wird die Textdatei gelöscht.

Ich vermute, dass wenn ich ein neues FileInputStream und ObjectInputStream deklariere, sie irgendwie die Informationen in dieser Textdatei löschen und sie leer machen.

Mein Code lautet wie folgt:

     stockInfo = new HashMap(10000);
     Scanner in = new Scanner(System.in);
     File file = new File("mp4output.txt");
     fos = new FileOutputStream(file);
     oos = new ObjectOutputStream(fos);
     fis = new FileInputStream(file);
     ois = new ObjectInputStream(fis);

So deklariere ich meine Ein-/Ausgabe-Ströme, um die hashMap einzulesen.

Dann versuche ich tatsächlich die hashMap einzulesen mit

           try {
           while (fis.available() > 0)   {
                 Stock test = (Stock) ois.readObject(); 
                 System.out.println("Aktie: " + test.getCompany());
                 System.out.println("Hoch: " + test.getHigh());
                 System.out.println("Volumen: " + test.getHigh());
                 System.out.println("Tief: " + test.getLow());
                 System.out.println("Schließen: " + test.getClose());
                 System.out.println("Öffnen: " + test.getOpen());
                 System.out.println("Bereich: " + test.getRange());
                 System.out.println("Durchschnittliche 52 Wochen: " + test.getFiftyAvg());
                 System.out.println("Aktueller Preis: " + test.getcurrentPrice());
                 }
           }
           catch (Exception ex) {
                 ex.printStackTrace();
           }

Es wird jedoch nie ausgeführt, weil fis.available() immer 0 zurückgibt, da die Datei sich selbst leert.

Ich habe das Gefühl, dass ich irgendwo einen sehr dummen Fehler gemacht habe, aber ich kann ihn nicht finden. Jede Hilfe wäre willkommen!

3voto

user2864740 Punkte 57014

Der FileOutputStream wird standardmäßig (oder immer, wenn nicht zum Anhängen erstellt) die Ausgabedatei abschneiden. Dieses Abschneiden erfolgt wenn der FOS erstellt wird, und bevor der FIS die Daten lesen kann.

Eine allgemeine Lösung in einem Fall wie diesem - wo die Eingabe und Ausgabe in dieselbe Datei erfolgen - besteht darin, alle Eingaben zu lesen, den Eingabestrom zu schließen und dann den Ausgabestrom zu öffnen und die neuen Daten zu schreiben. In diesem Fall funktioniert das Abschneideverhalten einwandfrei.

Mit diesem Gedanken könnte ein Gerüst so aussehen:

Map readStocks (ObjectInputStream ois) {
  // Alles lesen
}

void writeStocks (ObjectOutputStream oos, Map stocks) {
  // Alles schreiben
}

Map stocks;
// Verwenden Sie try-with-resources (Java 7+), um das Leben einfacher zu machen;
// der OIS (und der zugrunde liegende FIS) werden garantiert geschlossen
// nachdem dieser Block endet.
try (ObjectInputStream ois = new ObjectInputStream(
         new FileInputStream(file)) {
  stocks = readStocks(ois, stocks);
}

// Änderungen an den geladenen Daten vornehmen
// (z.B. entsprechend den vom Benutzer eingegebenen Daten)
updateStockData(stocks);

try (ObjectOutputStream oos = new ObjectOutputStream(
         new FileOutputStream(file)) {
  writeStocks(oos, stocks);
}

Die Object Input/Output Streams sind lediglich Wrapper über die zugrunde liegenden FIS/FOS, sind aber nicht für das Abschneiden oder die E/A auf niedrigerer Ebene verantwortlich.

Außerdem, während OIS/OOS wahrscheinlich für diese Aufgabe ausreichen, würde ich empfehlen, JSON zu verwenden, da die Verwendung von JSON mit POJO-Mappern (z.B. Gson) "relativ schmerzlos" ist und - wirklich warum ich es empfehle - die Ausgabe menschenlesbar ist.


Außerdem ist auf verschiedenen Betriebssystemen nicht klar definiert, wie mehrere FIS/FOS-Objekte auf derselben Quelle funktionieren. Die Dokumentation enthält diese vage Notiz (spezifiziert jedoch nichts über Interaktionen zwischen FIS/FOS-Objekten, bei denen keine Ausnahme ausgelöst wird).

Ein Dateiausgabestrom ist ein Ausgabestrom zum Schreiben von Daten in eine Datei oder in einen FileDescriptor. insbesondere ermöglicht es, dass eine Datei nur von einem FileOutputStream (oder einem anderen Dateischreibobjekt) gleichzeitig zum Schreiben geöffnet wird. In solchen Situationen schlagen die Konstruktoren in dieser Klasse fehl, wenn die betroffene Datei bereits geöffnet ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X