Reputation: 53481
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) {} }
Upvotes: 6
Views: 1485
Reputation: 72926
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.
Upvotes: 10