ObjectInputStream, close nach End of File

Anleitungen usw. rund um Java, Tutorials halt.

Moderator: wegus

Antworten
Thomas67
Beiträge: 57
Registriert: 12.09.2010, 19:17

ObjectInputStream, close nach End of File

Beitrag von Thomas67 » 09.01.2011, 22:24

Hallo

Ich will aus einem Objectinputstream Objecte einlesen, bis das Ende des Files erreicht ist.

Vielleicht hab ich nen Denkfehler, aber....
Das geht ja irgendwie nur mittels Endlosschleife, die irgendwann eine EndOfFileException auslöst, was dann ja auch ok ist

Aber:
Wo rufe ich dann das "close()" für den Objectinputstream auf?

Die Initialisierung ois = new ObjectInputStream(...) findet ja im try Block statt

Close im Try Block ist wegen der Endlosschleife unreachable
close in den catches oder im finally liefert immer die Meldung might not habe been initialized

Also...
wie schaff ich nen End of File Check UND ein ois.close();

Da steh ich grad aufm Schlauch...

Danke!
Thomas

Benutzeravatar
nigjo
Beiträge: 606
Registriert: 08.09.2009, 09:43
Wohnort: Aachen
Kontaktdaten:

Re: ObjectInputStream, close nach End of File

Beitrag von nigjo » 10.01.2011, 08:05

Hi

Ich würde es so machen, wie man jeden Dateizugriff umsetzen sollte.

Code: Alles auswählen

void writeFile(File fileName) throws IOException {
  OutputStream out = new XYZOutputStream(new FileOutputStream(fileName));
  try {
    // write your stuff
  } finally {
    out.close();
  }
}
Anstelle der Methode kann man auch einen weiteren try-catch Block setzen. Wichtig ist, dass hier "zwei" try-catch Blöcke sind. Im "äußeren" wird die Exception abgefangen und im "inneren" steht das finally mit dem close(). Die Datei muss dabei vor dem inneren Block geöffnet werden.

Dieses Vorgehen kann man beim Lesen und Schreiben anwenden und stellt sicher, dass die Datei immer ordentlich geschlossen wird. (Funktioniert natürlich auch mit den Reader/Writer Klassen)

Gruß
Jens

ps: Weiß jemand sicher, ob es die ARM Blöcke in Java7 geschafft haben oder kommen die erst in java8?
pps: Für die, die es nicht wissen: ARM Blöcke behandeln genau dieses Problem, dass "Ressourcen" automatisch "freigegeben" werden: http://blogs.sun.com/darcy/entry/projec ... d_arm_spec
Man sollte seine Werkzeuge kennen. Ansonsten haut man sich mit dem Hammer nur auf die Finger.

--
NetBeans Certified Engineer - Java Getriebe

Thomas67
Beiträge: 57
Registriert: 12.09.2010, 19:17

Re: ObjectInputStream, close nach End of File

Beitrag von Thomas67 » 10.01.2011, 20:54

Danke
Werd ich probieren

Aber lesen bis Fileende dann im inneren try als endlosschleife, oder?

Ansonsten müsst ich halt den Umweg gehn, zu Beginn der Datei die Anzahl der Datensätze abzuspeichern

Thomas

Benutzeravatar
smurfi
Site Admin
Beiträge: 1626
Registriert: 29.06.2006, 11:33
Wohnort: Wuppertal
Kontaktdaten:

Re: ObjectInputStream, close nach End of File

Beitrag von smurfi » 10.01.2011, 21:04

Hallo,

ich würde immer bis Dateiende gehen, nicht noch zusätzlich die Anzahl der Datensätze speichern.
Es ist manchmal auch komisch, das es Funktionen gibt die eine Exception werfen aber doch richtig funktionieren.

Gruß
Michael

Thomas67
Beiträge: 57
Registriert: 12.09.2010, 19:17

Re: ObjectInputStream, close nach End of File

Beitrag von Thomas67 » 10.01.2011, 21:46

Danke

Benutzeravatar
arittner
Beiträge: 3229
Registriert: 05.08.2008, 07:20
Wohnort: Südniedersachsen
Kontaktdaten:

Re: ObjectInputStream, close nach End of File

Beitrag von arittner » 12.01.2011, 09:25

Moin!

ObjectInputStream ist etwas doof, was die EOF-Behandlung betrifft.

Wenn man vorab nicht weiß, wie viele Objekte im Stream sind, geht man so vor:

Code: Alles auswählen

        ObjectInputStream inputStream = null;
        try {
            inputStream = new ObjectInputStream(... InputStream ...);
            
            Object obj = null;
            while ((obj = inputStream.readObject()) != null) {
                // Mach was
            }
        } catch (EOFException ex) {
            // Ende
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            Schließen
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
Meistens ist es aber so, dass man entweder eine fest definierte Anzahl von Objekten hat, oder Collections. Und wenn man die Collections selbst nicht speichert (sondern nur die Inhalte), dann sollte man m.E. die Anzahl mit speichern.

Spielen wir das mal gedanklich durch und generalisieren wir das.

"Das Speichern eines Objektes" ist ein Spezialfall von "Speichern von beliebig vielen Objekten"
"Das Speichern von einer bestimmten Menge von Objekten" ist ein Spezialfall von "Speichern von beliebig vielen Objekten"
"Das Speichern einer Collection" ist ein Spezialfall von "Speichern von beliebig vielen Collections"

Wenn Du als ein einzelnes oder exakt C (= bekannte hart kodierte konstante Anzahl) Objekte speicherst, dann kann man die Information zur Menge der Objekte ignorieren und wird beim Auslesen keine Exception erhalten.

Speicherst Du beliebig viele Objekte in einer Collection und speicherst Du die Collection, dann hast Du nur ein read/write-Object Aufruf und erhältst keine Exception

Speicherst Du eine exakte Anzahl von Collections, dann hast Du eine exakte Anzahl an read/write-Object Aufrufen und erhältst keine Exception.

Speicherst Du generell eine beliebige Anzahl von Collections (oder allgemein Objekten), kommst Du entweder um die Speicherung der Anzahl oder das Abfangen der EOFException nicht herum.

Da aber eine Collection (als Einzelobjekt) beim Speichern schon die Anzahl seiner Inhalte speichert, stellt sich die Frage, warum man das auch nicht machen sollte.

Wenn man Collections nutzt stellt sich überhaupt die Frage, warum man Einzelobjekte in einer Schleife speichert und sich Gedanken um Anzahl oder EOFException macht.


Wenn man Spezialfälle in der Programmierung vermeiden möchte, sollte man die Anzahl N = beliebig nicht auf den Spezielfall 1 oder C = konstant (wobei 1 wieder ein Spezielfall von C) reduzieren und immer von N >= 0 ausgehen.

Also, mein Vorschlag ;-)

Code: Alles auswählen

        Collection c = null;
        ObjectInputStream inputStream = null;
        try {
            inputStream = new ObjectInputStream(... InputStream ...);
            
            c = (Collection) inputStream.readObject();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            // Schließen
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return c;
Zwar würde ich das Exception-Hiding so nicht machen, sondern diese raus reichen, aber es geht ja erst mal um die Objekte.

So kann man ohne Probleme Arbeiten:


Code: Alles auswählen

if ( c !== null ) {
  for ( Object o : c) {
  
  }
}
Wenn man generell so vorgeht, ist das Speichern exakt eines Objektes auch zu schreiben:

Code: Alles auswählen

out.writeObject (Collections.singleton (o));
Für eine feste Anzahl an Objekten ist leider etwas mehr zu schreiben:

Code: Alles auswählen

out.writeObject (Arrays.asList (new Object [] {o1, o2, o3}));
Aber da das Sonderfälle sind, ist das wohl zu vernachlässigen. Üblicherweise hat man ja sowieso eine dynamisch gefüllte Collection.

Übrigens, wenn man sich daran gewöhnt hat, dieses Pattern anzuwenden, kommt man schnell zu JPA ;-)

Beste Grüße,
Josch.
JNBB/BeanDev-Blog | Twitter@beandev
Bild
Sun Certified Specialist for NetBeans IDE

Thomas67
Beiträge: 57
Registriert: 12.09.2010, 19:17

Re: ObjectInputStream, close nach End of File

Beitrag von Thomas67 » 12.01.2011, 20:52

Danke!

War auch mein Gedanke, das als Vector zu speichern, da ich die Objecte in Teilen des Prgramms dann sowieso sortieren will.
Doch ich war mir ned sicher, wenn ich nen Vector speichere, ob dann ein einzelnes write/read reicht

Danke Dir

Was is JPA?

Thomas

Benutzeravatar
arittner
Beiträge: 3229
Registriert: 05.08.2008, 07:20
Wohnort: Südniedersachsen
Kontaktdaten:

Re: ObjectInputStream, close nach End of File

Beitrag von arittner » 14.01.2011, 07:55

Moin!

Vergiss Vector, das ist noch aus dem letzten Jahrhundert. Verwende nur Collections aus der Collection-API (Set, List, Map und alle Implementationen). Vector, Hashtable und Dictonary sind deprecated.

JPA = Java Persistence API.

Beste Grüße,
Josch.
JNBB/BeanDev-Blog | Twitter@beandev
Bild
Sun Certified Specialist for NetBeans IDE

Thomas67
Beiträge: 57
Registriert: 12.09.2010, 19:17

Re: ObjectInputStream, close nach End of File

Beitrag von Thomas67 » 14.01.2011, 20:54

oooops

Danke!

Gibts eigentlich Erfahrungswerte, welche Größenordnung an Daten man in ein Set reinlädt?
Angenommen, ich hab ne Menge Datensätze, lädt man die in ein Set oder splittet man des lieber?

Kommt natürlich auf die Größe eines einzelnen Datensatzes an, und was man alles damit machen mag, aber gibts da irgendwelche Anhaltespunkte? Vielleicht nen Link dazu?

Thomas

Benutzeravatar
arittner
Beiträge: 3229
Registriert: 05.08.2008, 07:20
Wohnort: Südniedersachsen
Kontaktdaten:

Re: ObjectInputStream, close nach End of File

Beitrag von arittner » 16.01.2011, 13:38

Moin!

Erfahrungen sind da nicht sehr hilfreich. Die Größe der Objekte spielt eine Rolle und die liegen auf dem Heap. In Collections können Integer.MAX_INTEGER Referenzen (Pointer) zu Objekten gespeichert werden. Theoretisch. Praktisch wird man wegen fehlendem Arbeitsspeicher nicht an die Grenze kommen.

Wenn Du Dir jetzt schon Gedanken darum machst, sollte ein sofortiger Einstieg in JPA schon zwingend sein. Ein Persistence Provider hilft Dir dabei Objekte bei Bedarf in dem Arbeitsspeicher zu halten. Es erkennt unveränderte Objekte und wirft diese aus dem RAM.

Beste Grüße,
Josch.
JNBB/BeanDev-Blog | Twitter@beandev
Bild
Sun Certified Specialist for NetBeans IDE

Thomas67
Beiträge: 57
Registriert: 12.09.2010, 19:17

Re: ObjectInputStream, close nach End of File

Beitrag von Thomas67 » 16.01.2011, 19:16

Danke

na, dann mach ich nun mit JPA wohl die nächste Baustelle auf ;-)

Interessant, aber doch mühsam, wenn man am Tag nur ne gute Stunde zum JAvalernen und programmieren hat ;-))))

Schöne Woche!
Thomas

Antworten