I have a dummy Java Program, which I want to write in Clojure. It has a class which implements Serializable and a function which saves it. Since I have never written such programs in Clojure, I wanted to know what would be the correct way to approach this problem, what Clojure data structures, and api calls would you use?
import java. io. *;
public class Box implements Serializable
{
private int width; private int height;
public void setWidth(int w)
{ width =w;}
public void setHeight(int h)
{height = h;}
}
public static void main (String[] args)
{
Box myBox =new Box();
myBox.setWidth(50);
myBox.setHeight(20) ;
try {
FileoutputStream fs = new File("foo.ser");
ObjectOUtputStream os = new ObjectOutputStream(fs);
os.writeObject(myBox);
os . close () ;
} catch (Exception ex) {} }
To make a Java object serializable we implement the java. io. Serializable interface. The ObjectOutputStream class contains writeObject() method for serializing an Object.
For serializing the object, we call the writeObject() method of ObjectOutputStream class, and for deserialization we call the readObject() method of ObjectInputStream class. We must have to implement the Serializable interface for serializing the object.
To serialize an object hierarchy, you simply call the dumps() function. Similarly, to de-serialize a data stream, you call the loads() function.
If you want to do it in pure Clojure, use the Clojure reader.
(use 'clojure.contrib.duck-streams) (defn serialize [o filename] (binding [*print-dup* true] (with-out-writer filename (prn o)))) (defn deserialize [filename] (read-string (slurp* filename)))
Example:
user> (def box {:height 50 :width 20})
#'user/box
user> (serialize box "foo.ser")
nil
user> (deserialize "foo.ser")
{:height 50, :width 20}
This works for most Clojure objects already, but fails for most Java objects.
user> (serialize (java.util.Date.) "date.ser")
; Evaluation aborted.
No method in multimethod 'print-dup' for dispatch value: class java.util.Date
But you can add methods to the print-dup
multimethod to allow Clojure to print other objects readably.
user> (defmethod clojure.core/print-dup java.util.Date [o w]
(.write w (str "#=(java.util.Date. " (.getTime o) ")")))
#<MultiFn clojure.lang.MultiFn@1af9e98>
user> (serialize (java.util.Date.) "date.ser")
nil
user> (deserialize "date.ser")
#<Date Mon Aug 17 11:30:00 PDT 2009>
If you have a Java object with a native Java serialization method, you can just use that and not bother writing your own code to do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With