Toon posts:

[java] bug save/load objects na overriden writeObject()

Pagina: 1
Acties:

Verwijderd

Topicstarter
Beste mensen,

Ik heb 2 transient images die ik mee wil opslaan met de rest. Hiervoor heb ik de volgende functie geschreven (naar voorbeeld via google gevonden):
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void writeObject(ObjectOutputStream stream) throws java.io.IOException {
    stream.defaultWriteObject(); // write non-transient, non-static data
    PixelGrabber grabber_visLinks  = new PixelGrabber(view.imageLoader.imLinks, 0,0, -1, -1, true);
    PixelGrabber grabber_visRechts = new PixelGrabber(view.imageLoader.imRechts, 0,0, -1, -1, true);

    try {
      grabber_visLinks.grabPixels();
      grabber_visRechts.grabPixels();
    }
    catch (InterruptedException e) { }

    Object pix_visLinks     = grabber_visLinks.getPixels();
    Object pix_visRechts     = grabber_visRechts.getPixels();
    
    Dimension dim_visLinks = new Dimension(view.imageLoader.imLinks.getWidth(this),
                                        view.imageLoader.imLinks.getHeight(this));
    Dimension dim_visRechts = new Dimension(view.imageLoader.imRechts.getWidth(this),
                                         view.imageLoader.imRechts.getHeight(this));

    stream.writeObject(dim_visLinks);
    stream.writeObject(pix_visLinks);
    stream.writeObject(dim_visRechts);
    stream.writeObject(pix_visRechts);
  }

Dit lijkt allemaal goed te werken.

Bij het lezen krijg ik echter een OptionalDataException (EOF = true)

De leesfunctie: (Komt NIET bij de "Dimension1 gelezen" comment)
Java:
1
2
3
4
5
6
7
8
9
10
11
private void readObject(ObjectInputStream stream) throws java.io.IOException {
    try {
      stream.defaultReadObject(); // read non-transient, non-static data
      System.out.println("Standard data gelezen");
      Dimension dim_visLinks     = (Dimension)stream.readObject();
      System.out.println("Dimension1 gelezen");      
      Object img_visLinks         = (Image)stream.readObject();
      Dimension dim_visRechts     = (Dimension)stream.readObject();
      Object img_visRechts         = (Image)stream.readObject();
....
}

Ziet hier iemand wat ik fout doe, ik kijk mij er al helemaal scheel op.
Alvast heel erg bedankt,
Joost Pastoor

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Dit gaat er fout:
An attempt was made to read past the end of data consumable by a class-defined readObject or readExternal method.
Je moet zowiezo eerst schrijven voordat je iets kan lezen.


Exceptions printen gaat in een andere thread dan het printen van je normale output. Het kan dus zijn dat de exception later gegooid is.

Probeer eens alleen de dim_visLinks op te slaan en weer uit te lezen. Het plaatje schrijf je namelijk weg als een array en lees je als een Image. (Volgens mij moet dat een ClassCastException geven en niet de OptionalDataException.)

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Heb je gecontroleerd of alles goed wordt weggeschreven door even alles naar een file te schrijven?

Wie trösten wir uns, die Mörder aller Mörder?


Verwijderd

Topicstarter
Ik krijg dezelfde errors, ook als ik alleen de dimension wegschrijf. Hieronder wat extra code die misschien toch relevant is.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    public void windowClosing(WindowEvent e) 
    { 
        try
        {
            ObjectOutputStream out = new ObjectOutputStream(
            new FileOutputStream("save.dat"));
            out.writeObject(view.visArr);
            out.writeObject(view.visserArr);
            out.close();
        }   
        catch(IOException ioe)
        {
            System.out.println("I/O Exception: " + ioe);
        }

        view.dispose(); System.exit(0); 
    }

  private void writeObject(ObjectOutputStream stream) throws java.io.IOException {
    stream.defaultWriteObject(); // write non-transient, non-static data
    PixelGrabber grabber_visLinks  = new PixelGrabber(view.imageLoader.imLinks, 0,0, -1, -1, true);
    PixelGrabber grabber_visRechts = new PixelGrabber(view.imageLoader.imRechts, 0,0, -1, -1, true);

    try {
      grabber_visLinks.grabPixels();
      grabber_visRechts.grabPixels();
    }
    catch (InterruptedException e) { }

    Object pix_visLinks     = grabber_visLinks.getPixels();
    Object pix_visRechts    = grabber_visRechts.getPixels();
    
    Dimension dim_visLinks = new Dimension(view.imageLoader.imLinks.getWidth(this),
                                        view.imageLoader.imLinks.getHeight(this));
    Dimension dim_visRechts = new Dimension(view.imageLoader.imRechts.getWidth(this),
                                         view.imageLoader.imRechts.getHeight(this));

    stream.writeObject(dim_visLinks);
    //stream.writeObject(pix_visLinks);
    //stream.writeObject(dim_visRechts);
    //stream.writeObject(pix_visRechts);
  }


En het leesgedeelte:

In de constructor
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
                try
                {
                    System.out.println("Reading object!");
                    ObjectInputStream in = new ObjectInputStream(
                        new FileInputStream("save.dat"));


                    System.out.println("Reading object!");              
                    visArr      = (Vis[]) in.readObject();
                    System.out.println("Reading object!");              
                    visserArr   = (Visser[]) in.readObject();
                    
                    for(int visRow = 0; visRow < visArr.length; visRow++)
                    {
                        if(visArr[visRow] != null)  view.add(visArr[visRow]);
                    }
                    for(int visserRow = 0; visserRow < visserArr.length; visserRow++)
                    {
                        if(visserArr[visserRow] != null) 
                        { view.add(visserArr[visserRow]); 
                        visserArr[visserRow].repaint();
                        }
                    }
                    
                    view.validate();
                    
                    in.close();
                }   
                catch(ClassNotFoundException cnfe)
                {
                    System.out.println("ClassNotFound Exception: " + cnfe);
                }
                catch(OptionalDataException ode)
                {
                    System.out.println("Optional Data Exception: " + ode + " EOF: " + ode.eof + " Length: " + ode.length);
                }
                catch(IOException ioe)
                {
                    System.out.println("I/O Exception: " + ioe + ioe.getMessage());
                }
            }


En de overidden functie
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 private void readObject(ObjectInputStream stream) throws java.io.IOException {
    try {
      stream.defaultReadObject(); // read non-transient, non-static data
      System.out.println("Standard data gelezen");
      Dimension dim_visLinks    = (Dimension)stream.readObject();
      /*
      System.out.println("Dimension1 gelezen");      
      Object img_visLinks       = stream.readObject();
      Dimension dim_visRechts   = (Dimension)stream.readObject();
      Object img_visRechts  = stream.readObject();

      int [] pix_visLinks   = (int [])img_visLinks;
      int [] pix_visRechts  = (int [])img_visRechts;

      imageLoader.imLinks = createImage(new MemoryImageSource(dim_visLinks.width, dim_visLinks.height,
                                                     pix_visLinks, 0, dim_visLinks.width));
      imageLoader.imRechts = createImage(new MemoryImageSource(dim_visLinks.width, dim_visLinks.height,
                                                     pix_visRechts, 0, dim_visLinks.width));
        */
    }
    catch (ClassNotFoundException e) {
      throw new java.io.IOException();
    }
  }

Verwijderd

Topicstarter
Misschien pak ik dit probleem helemaal verkeerd aan.

Ik wil enkel een object (extends Canvas) saven en daarna laden, waarin in de paint method Images worden gebruikt.

Probleem met het transient zetten van de Image objecten is dat ze niet opnieuw geladen worden uit de savefile, en dus gelijk zijn aan NULL.

In de paint methode

if(image == null) image = getImage(bla)
g.drawImage(image)

zetten werkt niet

Hoe pakken jullie zoiets aan? Lijkt mij een erg algemeen verschijnsel??

Als iemand mij op de goede weg kan helpen, graag!

[ Voor 32% gewijzigd door Verwijderd op 05-01-2006 17:18 ]


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Ik doe het zonder te laden/opslaan. Ik teken gewoon elke keer alles opnieuw.

Je leest het bestand al in de constructor en slaat het pas op bij het sluiten van je programma. Om iets in je bestand te krijgen wat je kan lezen, moet je een keertje alleen opslaan.

Verwijderd

Topicstarter
Daos schreef op donderdag 05 januari 2006 @ 17:29:
Je leest het bestand al in de constructor en slaat het pas op bij het sluiten van je programma. Om iets in je bestand te krijgen wat je kan lezen, moet je een keertje alleen opslaan.
Ik snap niet helemaal wat je bedoeld?

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Dan maar een klein voorbeeldje:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;

public class IetsMetEenImage implements java.io.Serializable {
  transient Image image;
  transient int width;
  transient int height;

  IetsMetEenImage(boolean uitBestand) {
    if (uitBestand)
      lees();
    else
      maak();
  }

  public void maak() {
    height = 30;
    width = 50;
    int size = height * width;
    int[] pix = new int[size];

    int i = 0;
    int color = Color.red.getRGB();
    for (int y = 0; y < height; y ++) {
      if (y == 10) color = Color.white.getRGB();
      if (y == 20) color = Color.blue.getRGB();
      for (int x = 0; x < width; x ++)
        pix[i ++] = color;
    }

    MemoryImageSource source = new MemoryImageSource(width, height, pix, 0, width);
    image = new Button().createImage(source);
  }

  public void laatZien(String titelVanSchermpje) {
    JFrame f = new JFrame(titelVanSchermpje);
    JLabel l = new JLabel();
    l.setIcon(new ImageIcon(image));
    f.getContentPane().add(l);
    f.pack();
    f.setVisible(true);
  }


  public void schrijf() {
    try {
      ObjectOutputStream out = new ObjectOutputStream(
          new FileOutputStream("save.dat"));
      out.writeObject(this);
      out.close();
    }
    catch(IOException ioe) {
      System.out.println("I/O Exception: " + ioe);
    }
  }

  public void lees() {
    try {
      ObjectInputStream in = new ObjectInputStream(
          new FileInputStream("save.dat"));

      IetsMetEenImage imei = (IetsMetEenImage)in.readObject();
      in.close();

      this.image = imei.image;
      this.height = imei.height;
      this.width = imei.width;
    }
    catch(ClassNotFoundException cnfe) {
      System.out.println("ClassNotFound Exception: " + cnfe);
    }
    catch(OptionalDataException ode) {
      System.out.println("Optional Data Exception: " + ode + " EOF: " + ode.eof + " Length: " + ode.length);
    }
    catch(IOException ioe) {
      System.out.println("I/O Exception: " + ioe + ioe.getMessage());
    }
  }

  private void writeObject(ObjectOutputStream stream) throws java.io.IOException {
    stream.defaultWriteObject(); // write non-transient, non-static data

    PixelGrabber grabber  = new PixelGrabber(image, 0, 0, width, height, true);

    try {
      grabber.grabPixels();
    }
    catch (InterruptedException e) {
      System.out.println("Er ging ergens iets verkeerd!");
    }

    Object pix = grabber.getPixels();
    Dimension dim = new Dimension(width, height);

    stream.writeObject(dim);
    stream.writeObject(pix);
  }

  private void readObject(ObjectInputStream stream) throws java.io.IOException {
    try {
      stream.defaultReadObject(); // read non-transient, non-static data

      Dimension dim = (Dimension)stream.readObject();
      int[] pix = (int[])stream.readObject();

      width = dim.width;
      height = dim.height;

      MemoryImageSource source = new MemoryImageSource(width, height, pix, 0, width);
      image = new Button().createImage(source);
    }
    catch (ClassNotFoundException e) {
      throw new java.io.IOException();
    }
  }

  public static void main(String[] args) {
    IetsMetEenImage x = new IetsMetEenImage(false);
    x.laatZien("Nieuw");
    x.schrijf();

    IetsMetEenImage y = new IetsMetEenImage(true);
    y.laatZien("Uit bestand");
  }
}

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Voorzover ik kan zien serialiseer je alleen twee arrays. De klasse waarin je de writeObject hebt gedefinieerd wordt zelf niet geserialiseerd, dus die hele writeObject wordt nooit aangeroepen. Aangezien readObject wel wordt aangeroepen tijdens het deserializen lijkt het erop als één van die arrays objecten bevat van de klasse waarvan in de constructor de deserializatie wordt aangeroepen. Dan ga je dingen dubbel doen: een Object dat je deserializeert creeer je niet door zijn constructor aan te roepen en daarin zijn eigen variabelen expliciet te deserializen. Of ik snap gewoon niet wat je doet, maar dan moet je duidelijker aangeven wat in welke klasse zit. Als dit allemaal in dezelfde klasse zit en de arrays die klasse niet bevatten, dan is de vraag waarom in vredesnaam die readObject methode ooit wordt aangeroepen. Mocht het serializen en deserializen buiten dit object gebeuren, dan moet je die rits code uit de constructor trekken.

[ Voor 48% gewijzigd door Confusion op 05-01-2006 19:12 ]

Wie trösten wir uns, die Mörder aller Mörder?

Pagina: 1