Author | Message | Time |
---|---|---|
iago | Read the comments for more info on how this works/how to use it. [code]/* * Savable.java * * Created on March 29, 2004, 11:43 AM */ package bot.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * Any class that implements this can easily be saved and loaded. Basically, you can * call <PRE>this.save(filename)</PRE> and it will be saved to that file, or * <PRE>MyClass c = MyClass.load(filename)</PRE> to load it. * <P> * Note that every instance variable in the class must be either a primitive type or * a class that implements Serializable, otherwise, I'm told, something will blow up. * * @author iago */ abstract public class Savable implements Serializable { /** The class saves itself to the specified filename. * @param filename The file object to save the object as. * @throws IOException If there is a problem saving the file. */ public void save(File filename) throws IOException { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename)); out.writeObject(this); out.close(); } /** The class saves itself using a String for a filename rather than using a File object. * @param filename The path/name to save the file to. * @throws IOException If there is a problem saving the file. */ public void save(String filename) throws IOException { save(new File(filename)); } /** * Load and return an instance of the object. If there's an error during the load, * an exception is thrown. * @param filename The file object representing the file to load. * @return An instance of the object, loaded from the file. * @throws IOException if the file isn't found or if the file is an invalid format. */ public static Savable load(File filename) throws IOException { try { ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename)); Savable ret = (Savable) in.readObject(); in.close(); return ret; } catch(ClassNotFoundException e) { throw new IOException("Unable to read the file: " + e.toString()); } } /** * Load and return an instance of the object. If there's an error during the load, * an exception is thrown. * @param filename A String object representing the full or relative path to the file. * @return An instance of the object, loaded from the file. * @throws IOException if the file isn't found or if the file is an invalid format. */ public static Savable load(String filename) throws IOException { return load(new File(filename)); } } [/code] | April 14, 2004, 3:10 PM |
St0rm.iD | Why is this better than Serializable? | April 14, 2004, 7:07 PM |
iago | [quote author=St0rm.iD link=board=34;threadid=6299;start=0#msg55107 date=1081969648] Why is this better than Serializable? [/quote] It uses serializable. It just saves the effort of creating the ObjectOutputStream/ObjectInputStream and creating the File object. | April 14, 2004, 7:31 PM |
Myndfyr | [quote author=St0rm.iD link=board=34;threadid=6299;start=0#msg55107 date=1081969648] Why is this better than Serializable? [/quote] indeed, in fact I would say that Serializable is better. No offense, iago, but here's the problem... Say you have abstract class Car already made in a library. You want to derive class HondaAccord as well as make it Savable; however, you can't do that, because Java doesn't support double inheritence. You can have a ton of interfaces (such as Serializable) on a class, but you can't have: [code] package MyndFyre.Vehicles; import Generics.Car; public class HondaAccord extends Car, Savable { //... } [/code] but you can have: [code] package MyndFyre.Vehicles; import Generics.Car; public class HondaAccord extends Car implements Serializable { //... } [/code] | April 14, 2004, 7:32 PM |
iago | If you need to extend something else, then your superclass can (probably) extends Savable. If not, then just use serializable and write the extra code. I found myself writing the same code over and over to do the same thing: save a serializable. Mainly classes that I was using to store preferences, which wouldn't extend anything to begin with. So I wrote a class to extend to save me time, and it has. So my point is, Savable can save you a little time, but if not go ahead and use Serializable :P | April 14, 2004, 7:46 PM |
St0rm.iD | [code] import java.io.*; public class Saver { public static void save(String filename, Serializable o) throws IOException { new ObjectOutputStream(new FileOutputStream(filename)).writeObject(o); } } [/code] | April 15, 2004, 10:49 PM |
iago | [quote author=St0rm.iD link=board=34;threadid=6299;start=0#msg55326 date=1082069368] [code] import java.io.*; public class Saver { public static void save(String filename, Serializable o) throws IOException { new ObjectOutputStream(new FileOutputStream(filename)).writeObject(o); } } [/code] [/quote] Ugh@* imports, clarity is more important than time. That doesn't take care of loading. Doesn't close the file (good coding practice). I considered doing a static class before, but I found mine much more convenient for what I need. | April 15, 2004, 11:06 PM |
St0rm.iD | I'll bet you a cent that it does close the file. | April 15, 2004, 11:37 PM |
iago | It's better to close the file explicitly. But, how does it know to? There's no destructors in Java. | April 16, 2004, 12:13 AM |
Myndfyr | [quote author=iago link=board=34;threadid=6299;start=0#msg55348 date=1082074402] It's better to close the file explicitly. But, how does it know to? There's no destructors in Java. [/quote] OK iago, here: [code] // just for you, even though * syntax doesn't do anything bad... import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class IOer { public static void save(String filename, Serializable o) throws IOException { FileOutputStream fos = new FileOutputStream(filename); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(o); oos.close(); fos.close(); } public static Object load(String filename) throws IOException { FileInputStream fos = new FileInputStream(filename); ObjectInputStream oos = new ObjectInputStream(fos); Object o = oos.readObject(); oos.close(); fos.close(); return o; } } [/code] | April 16, 2004, 1:04 AM |
iago | You're right, * imports don't hurt anything programatically, but it clarifies code. If I see a class I don't know, say, for instance, file, I can look at the imports and know to look up "java.io.file". As for the rest of it, a static class would be ok too, but it doesn't matter :) | April 16, 2004, 1:26 AM |