Java: object to byte[] and byte[] to object converter (for Tokyo Cabinet)
Asked Answered
A

6

73

I need to convert objects to a byte[] to be stored in the Tokyo Cabinet key-value store. I also need to unbyte the byte[] to an Object when reading from the key-value store.

Are there any packages out there that will help me with this task? Or would the best solution to implement it myself?

Aliform answered 17/9, 2010 at 14:10 Comment(3)
Make your class Serializable, then use the answer at [ Java Serializable Object to Byte Array ](#2837146).Erato
it is not an exact duplicate, although it appears soCaplan
If the object is not Serializable but Parcealable or a Parcel, you can use marshall and unmarshall methods, see (https://mcmap.net/q/275421/-how-to-marshall-and-unmarshall-a-parcelable-to-a-byte-array-with-help-of-parcel)Otterburn
K
175
public static byte[] serialize(Object obj) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(out);
    os.writeObject(obj);
    return out.toByteArray();
}
public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
    ByteArrayInputStream in = new ByteArrayInputStream(data);
    ObjectInputStream is = new ObjectInputStream(in);
    return is.readObject();
}
Kaneshakang answered 17/9, 2010 at 14:33 Comment(15)
don't forget to call is.close and in.close.Plutocracy
is.close and in.close are not needed in this case because it's an in-memory stream. The only thing it would do here is make it slower and more verbose. But I understand the IDE might flag the code above because the stream is not closed.Kaneshakang
I don't think it will make slower, it is only an empty method so the time difference must be very low. But you are right: Closing a ByteArrayOutputStream has no effect.Java Doc Awesome :DPlutocracy
What if the object to be serialized is of type InputStream?Kunlun
@ArthurEirich Generally it would still work, but it might not do what you expect.Kaneshakang
@ThomasMueller Unfortnately, "os.writeObject(obj);" would cause a NotSerializableException as InputStream does not implement the Serializable interface =(Kunlun
@ArthurEirich OK, it would only work if the InputStream implementation implements Serializable.Kaneshakang
@all if the object is Parcelable then what is solution ??Maighdlin
@ZalaJanaksinh that's a different question. This question is about Java, not Android.Kaneshakang
are there any memory limitations using this method?Churchwarden
Yes, those operations can run out of memory, specially deserialize: it's relatively easy to construct a (small) byte array that will be deserialized into a extremely large object, which will cause out of memory. There is also a security risk to deserialize any byte array, but this answer is not about security aspects.Kaneshakang
this method is causing "IOException: java.io.StreamCorruptedException: invalid stream header: 7B227374", any idea why its doing so?Pinite
@Pinite probably because you tried to deserialize, but the input (the byte array) contains a JSON text file starting with {"st.... That won't work. You can only deserialize things that were serialized with the above method. To read a JSON file, try searching for "convert JSON to Java object" or similar.Kaneshakang
code not work for offheap cache like ohc. when performing benchmark, the code will throw nullpointer exception.Prevost
@Prevost I think you are not using it correctly. Please ask a new question.Kaneshakang
C
14

If your class extends Serializable, you can write and read objects through a ByteArrayOutputStream, that's what I usually do.

Cadman answered 17/9, 2010 at 14:14 Comment(3)
All types included as variables in your class (and all types in those types, and so on) also need to be Serializable.Tinstone
Actually he'll need an ObjectOutputStream to wrap the BAOS too... But yeah, that's the easiest way to go.Illegal
I'd consider using something other than Java's built-in serialization, too - JBoss serialization, JSerial, Avro, etc, or an XML format like XStream or Javolution marshalling plus gzip. Standard serialization is not particularly fast, and although its marginal space efficiency is good, there's quite a bit of per-stream overhead.Antwanantwerp
H
11

Use serialize and deserialize methods in SerializationUtils from commons-lang.

Hemihydrate answered 31/3, 2014 at 5:16 Comment(0)
W
6

You can use ObjectMapper

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectClass object = objectMapper.readValue(data, ObjectClass.class);
Wilma answered 23/12, 2020 at 12:28 Comment(0)
C
5

You can look at how Hector does this for Cassandra, where the goal is the same - convert everything to and from byte[] in order to store/retrieve from a NoSQL database - see here. For the primitive types (+String), there are special Serializers, otherwise there is the generic ObjectSerializer (expecting Serializable, and using ObjectOutputStream). You can, of course, use only it for everything, but there might be redundant meta-data in the serialized form.

I guess you can copy the entire package and make use of it.

Caplan answered 17/9, 2010 at 14:14 Comment(1)
link is broken!Gerhardine
C
0

If you do not want to serialize you can use object mapper

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());

ByteArrayOutputStream out = new ByteArrayOutputStream();
objectMapper.writeValue(out,obj);
byte[] data = out.toByteArray();

When should we implement Serializable interface?

Championship answered 24/6, 2021 at 7:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.