10. februar 2003 - 13:32Der er
30 kommentarer og 1 løsning
Serializing:How to med ArrayList,som består af en række objekter?
Hejsa, Jeg er helt newbie hvad angår serializing. Jeg troede jeg kunne bruge en metode i understående stil. Jeg har implementeret serielizable i de classer som jeg skal have ned på fil. Håber noget kan tilrette min metode eller give mig et andet eksempel som jeg kan arbejde ud fra. Hvad betyder flush i øvrigt når man arbejder med en Stream? at man smider den væk(samler garbage collector ikke selv den op?)?
public void objectToFile(Serializable structure, String filename) { try{ ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(filename)); out.writeObject(structure); out.flush(); out.close(); } catch(IOException e) {System.out.println("IO problem "+e.getMessage());} }
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
streams har næsten altid en buffer, der samler bogstaver op til den har fx 100 bogstaver, når bufferen har nok skriver den dem allesammen til den fil eller device den stem er sat op for. På den måde sparer den en masse tid fordi altmulig baggrunds-admin (er diske klan, har jeg retten til denne device, ...) kun behøver at ske een gang for hver 100 bytes istedet for for hver eneste byte.
Men det medfører så også at når der ikke er mere at sende til en stream, så vil der sikkert stadig ligge noget i bufferen der ikke er sendt. metoden flush kan så bruges til at sige "Det skal sendes nu, selvomogså bufferen ikke er 'fuld nok'."
Faktisk tror jeg flush er unædvendig her. Jeg tror (men er ikke 100% sikker på) at dit kald til close lige bagefter automatisk vil flushe bufferen hvis der er noget i den der ikke er sendt.
med din metode objectToFile genåbner du din fil for hvert objekt der skal sendes. det går ikke godt da nr 2 objekt sp over skriver det første, osv osv. Din outputstream bør ligge udenfor metoden og blive åbnet separat.
Jeg har nu flyttet output streamen uden for metode, men får denne fejl: symbol : method objectToTile (java.util.List,java.io.ObjectOutputStream) location: class run objectToTile(fliste,out); ^ 1 error
Tool completed with exit code 1
Jeg har plukket lidt ud af koden:
List fliste = new ArrayList();
fliste.add(a); //det er objekter der tilføjes til fliste fliste.add(b); fliste.add(c); fliste.add(d);
ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("test")); objectToTile(fliste,out);
public void objectToFile(Serializable structure, ObjectOutputStream out) { try{ out.writeObject(structure); out.close(); } catch(IOException e) { System.out.println("IO problem "+e.getMessage());} }
Jeg får samme fejl selvom jeg nu har flyttet close() til efter metode kaldet. objectToFile er selvf. en selvstændig metode.
public static void main(String[] arguments) { List fliste = new ArrayList(); List filmliste = new ArrayList(); List temp = new ArrayList();
Biograf Palads = new Biograf("Palads"); Biograf Kinop = new Biograf("Kinopalæet");
Sal K1 = new Sal (1, Kinop, 100); Sal K2 = new Sal (2, Kinop, 200); Sal K3 = new Sal (3, Kinop, 300); Sal K4 = new Sal (4, Kinop, 400); Sal P1 = new Sal (4, Palads, 100); Sal P2 = new Sal (4, Palads, 200); Sal P3 = new Sal (4, Palads, 300); Sal P4 = new Sal (4, Palads, 400); Film F1 = new Film ("The Rock","Action"); Film F2 = new Film ("Ridskolen","Porno"); Film F3 = new Film ("Gladiator","Action"); Film F4 = new Film ("Polle", "Komedie");
filmliste.add(new Film ("The Rock","Action")); filmliste.add(new Film ("Ridskolen","Porno")); filmliste.add(new Film ("Gladiator","Action")); filmliste.add(new Film ("Polle", "Komedie"));
Forestilling a = new Forestilling (F4, P3,"28-Feb-2003 12:00"); Forestilling b = new Forestilling (F4, K3,"28-Feb-2003 14:30"); Forestilling c = new Forestilling (F4, K3,"02-Mar-2003 17:00"); Forestilling d = new Forestilling (F3, P4,"03-Feb-2003 14:00");
fliste.add(a); fliste.add(b); fliste.add(c); fliste.add(d); ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("test")); objectToTile(fliste,out); out.close(); }
add tilføjer bare et objekt til fliste på normal vis. Et uddrag at Forestillingen klassen:
public class Forestilling implements Serializable { public Sal sal; public Film film; public int counter=0; public Date d; private DateFormat df = new SimpleDateFormat("dd-MMM-yyyy HH:mm");
public Forestilling(Film filmV, Sal salV, String date) { film=filmV; sal=salV; try {d = df.parse(date);} catch (ParseException e) {} }
Det var da noget nemmere :o) Men hvis jeg nu vil lave det som en metode og kalde metoden fra min main metode, så får jeg jo lidt bøvl med static contra non-static. Hvordan kan jeg slippe uden om det? Man kan åbenbart ikke lave en " static ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("test.dat"));"
public class X { private static ObjectOutputStream out; private static void dowrite() { out.writeObject(something); } public static void main(String[] args) { out = new ObjectOutputStream( new FileOutputStream("test.dat")); ... dowrite(); } }
Men jeg synes, at det er meget dårligt design.
Jeg vil anbefale noget i retning af:
public class X { private static ObjectOutputStream out; private void dowrite(ObjectOutputStream out) { out.writeObject(something); } public static void main(String[] args) { out = new ObjectOutputStream( new FileOutputStream("test.dat")); X x = new X(); ... x.dowrite(out); } }
public class X { private void dowrite(ObjectOutputStream out) { out.writeObject(something); } public static void main(String[] args) { ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("test.dat")); X x = new X(); ... x.dowrite(out); } }
public class X { private OutputObjectStream out = null; public void setOutput(ObjectOutputStream out) { this.out = out; } public void dowrite() { out.writeObject(something); } public static void main(String[] args) { ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("test.dat")); X x = new X(); ... x.setOutput(out); x.dowrite(); } }
Jeg håber ikke at jeg forvirrer dig med den mange eksempler.
Jeg vil bare gerne vise nogle af de mange muligheder der er.
En måde at læse dataene over i listen på igen er så: try{ //read the object back in ObjectInputStream in = new ObjectInputStream(new FileInputStream("yesyes.dat")); fliste.add(in.readObject()); in.close(); } catch(IOException ee) {System.out.println("IO problem "+ee.getMessage());} catch (ClassNotFoundException ee) {System.out.println("Class problem(ikke fundet "+ee.getMessage());}
Men hvor meget information gennem den i yesyes.dat, Hvis nu de forskellige objekter der ligger i fliste består af andre objekter, så er gemmer den vel også dem?
Den gemmer alt d.v.s. alle members ("felter") i klassen - undtagen dem du eksplicit beder den lade være med at gemme ved at give attributten transient.
Også objekter der er gemt i objekter.
Hvis et objekt ikke kan gemmes fordi det ikke er serializable så får du en exception på gemme tidspunkt.
Så du skulle have det hele.
Det største problem du skal være opmærksom på er, hvis du skriver et objekt med en version af klassen og så forsøger at læse det med en nyere version af klassen. Det virker ikke godt !
Der var jeg vist lidt for hurtig :o( Jeg har dog ingen problemer med:
ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("film.dat")); out.writeObject(fliste);
Men når jeg så vil læse det ind med: try{ //read the object back in ObjectInputStream in = new ObjectInputStream(new FileInputStream("film.dat")); fTliste.add(in.readObject()); in.close(); } catch(IOException ee) {System.out.println("IO problem "+ee.getMessage());} catch (ClassNotFoundException ee) {System.out.println("Class problem(ikke fundet "+ee.getMessage());}
og printe det ud med: Film current = null; for( int i = 0; i < fTliste.size(); i++ ) { current = (Film)fTliste.get(i); System.out.println("titel: " +current.getTitle()); System.out.println("genre: " +current.getGenre()); }
Får jeg en fejl når jeg kører det, ikke når jeg compilere det. Fejlen er: Exception i thread "main" java.lang.ClassCastException at run.main(run.java:131)
lidt mer kode... Film current = null; for( int i = 0; i < fTliste.size(); i++ ) { Linie 131 --> current = (Film)fTliste.get(i); System.out.println("titel: " +current.getTitle()); System.out.println("genre: " +current.getGenre()); }
Har du en ide om hvad det kan være? smider gerne lidt flere point hvis det er... mvh Torben
Det er lidt af en smøre, men her kommer den: IO problem ved skrivning af Saede java.io.NotSerializableException: Saede ..... ARHHHH jeg tæver mig selv!
måske det vil hjælpe en smule med "implements Serializable". Men nu fandt vi da frem til fejlen, skønt :o)
Ja, men det kan nu godt være lidt irreterende med "åndsvage fejl"... Måske man skulle begynde at gøre mere brug af printStackTrace, den viser jo ret åbenlyst fejlen :o)
Nå lige en sidste ting, hvis det er iorden.. som det er nu tilføjer jeg arrays af objekter til min arraylist saedeliste:
Saede saedeP4[] = new Saede[P4.pladser]; for(int i=1; i<=P4.pladser; i++) { String tal = String.valueOf(i); saedeP4[i-1]=new Saede(P4,i); } saedeliste.add(saedeK1);
Men hvordan kommer jeg så ind til objektet igen?
Saede b=null; b=(Saede)saedeliste.get(0); //virker ikke :o(
Altså hvis jeg nu fx gerne vil tilgå saedeK1[i] i saedelisten, hvordan gør jeg så det? saedeK1[i] er det første objekt i listen.
Det fungerer perfekt. Programmet virker nu efter hensigten. Jeg takker endnu engang for hjælpen :o) Mvh Torben
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.