Avatar billede skalle Novice
02. december 2007 - 06:04 Der er 12 kommentarer og
1 løsning

At skrive og læse objekter til filer

Jeg vil gerne kunne gemme et ojekt som indeholder HashMaps og ArrayLists direkte til en fil.

Jeg har implementeret Serializable på alle de klasser der bliver integreret i det objekt som skal gemmes...

jeg har fundet ud af at jeg skal skrive metoderne 'private static void writeObject(OutputStream out) throws IOException' og 'private static void readObject(InputStream in) throws IOException, FileNotFoundException'.

jeg kan bare ikke finde nogle eksempler hvor folk skriver disse metoder...

Jeg går ud fra at jeg fx ind i writeObject(OutputStream out) skal sørge for at alle fields bliver skrevet til outputstreamen det er nok bedre hvis jeg laver et eksempel:

public class ObjektetSomSkalGemmesTilFil implements Serializable
{

}




men her har jeg et problem med metoderne
Avatar billede arne_v Ekspert
02. december 2007 - 06:12 #1
Du skriver bare dit objekt til en ObjectOutputStream.

Du skal kun override writeObject, hvis du skal lave noget specielt.
Avatar billede arne_v Ekspert
02. december 2007 - 06:21 #2
Eksempel:

package december;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class SerDeser {
    public static void main(String[] args) throws Exception {
        SerTest o1 = new SerTest("Demo");
        o1.add("A");
        o1.add("BB");
        o1.add("CCC");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\ser.dat"));
        oos.writeObject(o1);
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\ser.dat"));
        SerTest o2 = (SerTest)ois.readObject();
        System.out.println(o1 + " -> " + o2);
    }
}

class SerTest implements Serializable {
    private String name;
    private List<String> vals;
    public SerTest(String name) {
        this.name = name;
        vals = new ArrayList<String>();
    }
    public void add(String v) {
        vals.add(v);
    }
    public String toString() {
        return "[" + name + ":" + vals + "]";
    }
}
Avatar billede skalle Novice
02. december 2007 - 07:04 #3
damn.. jeg kom lige til at tabbe og trykke enter :)...

public class ObjektetSomSkalGemmesTilFil implements Serializable
{
    private static final long serialVersionUID = 1L;
    private ArrayList<House> aList;
    private HashMap<String, House> houseMap;
    private String;
   
    pulic ObjektetSomSkalGemmesTilFil(){}
...

    private static void writeObject(OutputStream out) throws IOException
    {
/**at sørge for at elementerne i arraylisten bliver gemt som deep copy og ikke blot referencer**/
              for(int i = 0; i< = aList.size(); i++)
              {
                      out.writeObject(aList.get(i));
              }
              /**jeg ved slet ikke hvordan jeg skal begynde at gemme hashMappet**/

    }
}
Avatar billede skalle Novice
02. december 2007 - 07:10 #4
hej Arne V

tak for det superhurtige svar:)
Hvaf mener du med at det skal være specielt hvis jeg skal behøve at overskrive de to skriv og læs objekt metoder?

Kan HashMaps iøvrigt gemmes med din løsning?
Avatar billede arne_v Ekspert
02. december 2007 - 16:09 #5
Ja. Du kan også gemme en HashMap på den måde.
Avatar billede arne_v Ekspert
02. december 2007 - 16:10 #6
Jeg mener hvis du har et behov for at gøre noget anderledes end Java standard.
Avatar billede arne_v Ekspert
02. december 2007 - 16:45 #7
Her er et eksempel hvor man krypterer et pasword:

package december;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class SpecialSerDeser {
    public static void main(String[] args) throws Exception {
        SensitiveUnprotected o1 = new SensitiveUnprotected("arne", "hemmeligt");
        ObjectOutputStream oosup = new ObjectOutputStream(new FileOutputStream("C:\\ser_up.dat"));
        oosup.writeObject(o1);
        oosup.close();
        ObjectInputStream oisup = new ObjectInputStream(new FileInputStream("C:\\ser_up.dat"));
        SensitiveUnprotected o2 = (SensitiveUnprotected)oisup.readObject();
        oisup.close();
        System.out.println(o1 + " -> " + o2);
        SensitiveProtected.setKey("hemmelighemmelig");
        SensitiveProtected o3 = new SensitiveProtected("arne", "hemmeligt");
        ObjectOutputStream oosp = new ObjectOutputStream(new FileOutputStream("C:\\ser_p.dat"));
        oosp.writeObject(o3);
        oosp.close();
        ObjectInputStream oisp = new ObjectInputStream(new FileInputStream("C:\\ser_p.dat"));
        SensitiveProtected o4 = (SensitiveProtected)oisp.readObject();
        oisp.close();
        System.out.println(o3 + " -> " + o4);
    }
}

class SensitiveUnprotected implements Serializable {
    private String un;
    private String pw;
    public SensitiveUnprotected(String un, String pw) {
        this.un = un;
        this.pw = pw;
    }
    public String getUn() {
        return un;
    }
    public String getPw() {
        return pw;
    }
    public String toString() {
        return "[" + un + "," + pw + "]";
    }
}

class SensitiveProtected implements Serializable {
    private transient String un;
    private transient String pw;
    public SensitiveProtected(String un, String pw) {
        this.un = un;
        this.pw = pw;
    }
    public String getUn() {
        return un;
    }
    public String getPw() {
        return pw;
    }
    public String toString() {
        return "[" + un + "," + pw + "]";
    }
    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.writeObject(un);
        oos.writeObject(encrypt(pw.getBytes()));
    }
    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        un = (String)ois.readObject();
        pw = new String(decrypt((byte[])ois.readObject()));
    }
    private static String key;
    public static void setKey(String newkey) {
        key = newkey;
    }
    private static byte[] encrypt(byte[] plaindata) {
        try {
            Cipher aes = Cipher.getInstance("AES");
            SecretKey aeskey = new SecretKeySpec(key.getBytes(), "AES");
            aes.init(Cipher.ENCRYPT_MODE, aeskey);
            return aes.doFinal(plaindata);
        } catch (NoSuchAlgorithmException e) {
            return null;
        } catch (NoSuchPaddingException e) {
            return null;
        } catch (InvalidKeyException e) {
            return null;
        } catch (IllegalBlockSizeException e) {
            return null;
        } catch (BadPaddingException e) {
            return null;
        }
    }
    private static byte[] decrypt(byte[] cipherdata) {
        try {
            Cipher aes = Cipher.getInstance("AES");
            SecretKey aeskey = new SecretKeySpec(key.getBytes(), "AES");
            aes = Cipher.getInstance("AES");
            aeskey = new SecretKeySpec(key.getBytes(), "AES");
            aes.init(Cipher.DECRYPT_MODE, aeskey);
            return aes.doFinal(cipherdata);
        } catch (InvalidKeyException e) {
            return null;
        } catch (NoSuchAlgorithmException e) {
            return null;
        } catch (NoSuchPaddingException e) {
            return null;
        } catch (IllegalBlockSizeException e) {
            return null;
        } catch (BadPaddingException e) {
            return null;
        }
    }
}
Avatar billede arne_v Ekspert
02. december 2007 - 16:46 #8
Men jeg må have serialiseret i hundredevis af forskellige klasser gennem årene og det er
kun sket en enkelt gang at der har været custom readObject/writeObject !
Avatar billede skalle Novice
02. december 2007 - 21:54 #9
fedt :)
jeg holder mig fra kryptering lidt endnu dog:)
mange tak for hjælpen!
Avatar billede skalle Novice
02. december 2007 - 21:55 #10
vil du ikke lige skrive et eller andet som et 'svar' så jeg kan gi point?

mvh Anders
Avatar billede arne_v Ekspert
02. december 2007 - 23:17 #11
kommer her
Avatar billede arne_v Ekspert
02. december 2007 - 23:18 #12
Man kan også bruge det til andet end at kryptere med. Men man skal have et specielt behov
for at man vil override de metoder.
Avatar billede skalle Novice
03. december 2007 - 06:28 #13
Hej Arne V fedt tak for super tips og insider råd:D
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester