How to serialize ByteBuffer
Asked Answered
R

4

8

I wish to send a java.nio.ByteBuffer accross a network using RMI, however ByteBuffer isn't serializable. I've tried the following custom class to no avail:

public class NetByteBuffer implements java.io.Serializable {

ByteBuffer buffer;

public NetByteBuffer(ByteBuffer buffer) {
    this.buffer = buffer;
}

public ByteBuffer getByteBuffer() {
    return this.buffer;
}

}

The client still gets a non-serialzable exception. Any ideas?

Thanks

Regalia answered 20/10, 2010 at 22:1 Comment(0)
E
7

You can't. You'd better obtain the byte[] and send it instead and reconstruct the ByteBuffer on the other side. You are of course losing the advantages of it being a buffer.

Envelope answered 20/10, 2010 at 22:15 Comment(2)
What advantages would I be loosing? This is for a PDF file from Filechannel.mapRegalia
If you are using ByteBuffer without a specific reason, then perhaps you are safe using the byte array ;)Envelope
T
5

Like others said ByteBuffer is a wrap of a buffer of bytes so if you need to serialize your class is better to change to byte[] and use ByteBuffer in the classes which are reading/writing data into this bean.

But if you need to serialize a ByteBuffer property (for example usign Cassandra blobs) you can always implement a custom serialization (check this url http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html).

The main points are:

  1. mark ByteBuffer as transient (so it's not serialized by default)
  2. implement your own read/write for serialization where ByteBuffer --> byte[] when serializing and byte[] --> ByteBuffer on deserializing.

Try this class and let me know if this works for you:

public class NetByteBuffer implements java.io.Serializable {
    private static final long serialVersionUID = -2831273345165209113L;

    //serializable property
    String anotherProperty;

    // mark as transient so this is not serialized by default
    transient ByteBuffer data;

    public NetByteBuffer(String anotherProperty, ByteBuffer data) {
        this.data = data;
        this.anotherProperty = anotherProperty;
    }

    public ByteBuffer getData() {
        return this.data;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        // write default properties
        out.defaultWriteObject();
        // write buffer capacity and data
        out.writeInt(data.capacity());
        out.write(data.array());

    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        //read default properties
        in.defaultReadObject();

        //read buffer data and wrap with ByteBuffer
        int bufferSize = in.readInt();
        byte[] buffer = new byte[bufferSize];
        in.read(buffer, 0, bufferSize);
        this.data = ByteBuffer.wrap(buffer, 0, bufferSize);
    }

    public String getAnotherProperty() {
        return anotherProperty;
    }

}
Towboat answered 4/11, 2015 at 11:0 Comment(0)
Q
1

You probably need to say more about why you're serializing a byte buffer. If you're simply trying to send a bunch of bytes across the network, @Bozho's answer has got you covered.

If you actually want to send across a ByteBuffer including its contents and state, you probably need to rethink your design, or at the very least explain it here so others can provide more direction.

Quart answered 21/10, 2010 at 0:53 Comment(0)
V
-1

Long way but your goal can be accomplish:

u can create a remote object with instance variable type of "ByteBuffer" and defined the getter and setter remote methods to access that variable.

Vernacularism answered 21/10, 2010 at 1:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.