序列化的Java通过的ByteBuffer&CQL 3个对象卡桑德拉1.2

我拼凑下面的代码,这并不做任何事情复杂 - 只是创建一个byte []变量,其写入BLOB字段中卡桑德拉(V1.2,通过新的Datastax CQL库),然后读回出一次。

当我把它在它的3个单元长,当我看到它回到它的84元素长... ...! 这意味着,实际上,我试图做(Java对象序列)的东西失败,并org.apache.commons.lang.SerializationException: java.io.StreamCorruptedException: invalid stream header: 81000008再次尝试反序列化时出错。

以下是一个演示我的问题的一些示例代码:

import java.nio.ByteBuffer; import org.apache.commons.lang.SerializationUtils; import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Host; import com.datastax.driver.core.Metadata; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; public class TestCassandraSerialization { private Cluster cluster; private Session session; public TestCassandraSerialization(String node) { connect(node); } private void connect(String node) { cluster = Cluster.builder().addContactPoint(node).build(); Metadata metadata = cluster.getMetadata(); System.out.printf("Connected to %s\n", metadata.getClusterName()); for (Host host: metadata.getAllHosts()) { System.out.printf("Datacenter: %s; Host: %s; Rack: %s\n", host.getDatacenter(), host.getAddress(), host.getRack()); } session = cluster.connect(); } public void setUp() { session.execute("CREATE KEYSPACE test_serialization WITH replication = {'class':'SimpleStrategy', 'replication_factor':1};"); session.execute("CREATE TABLE test_serialization.test_table (id text PRIMARY KEY, data blob)"); } public void tearDown() { session.execute("DROP KEYSPACE test_serialization"); } public void insertIntoTable(String key, byte[] data) { PreparedStatement statement = session.prepare("INSERT INTO test_serialization.test_table (id,data) VALUES (?, ?)"); BoundStatement boundStatement = new BoundStatement(statement); session.execute(boundStatement.bind(key,ByteBuffer.wrap(data))); } public byte[] readFromTable(String key) { String q1 = "SELECT * FROM test_serialization.test_table WHERE id = '"+key+"';"; ResultSet results = session.execute(q1); for (Row row : results) { ByteBuffer data = row.getBytes("data"); return data.array(); } return null; } public static boolean compareByteArrays(byte[] one, byte[] two) { if (one.length > two.length) { byte[] foo = one; one = two; two = foo; } // so now two is definitely the longer array for (int i=0; i<one.length; i++) { //System.out.printf("%d: %s\t%s\n", i, one[i], two[i]); if (one[i] != two[i]) { return false; } } return true; } public static void main(String[] args) { TestCassandraSerialization tester = new TestCassandraSerialization("localhost"); try { tester.setUp(); byte[] dataIn = new byte[]{1,2,3}; tester.insertIntoTable("123", dataIn); byte[] dataOut = tester.readFromTable("123"); System.out.println(dataIn); System.out.println(dataOut); System.out.println(dataIn.length); // prints "3" System.out.println(dataOut.length); // prints "84" System.out.println(compareByteArrays(dataIn, dataOut)); // prints false String toSave = "Hello, world!"; dataIn = SerializationUtils.serialize(toSave); tester.insertIntoTable("toSave", dataIn); dataOut = tester.readFromTable("toSave"); System.out.println(dataIn.length); // prints "20" System.out.println(dataOut.length); // prints "104" // The below throws org.apache.commons.lang.SerializationException: java.io.StreamCorruptedException: invalid stream header: 81000008 String hasLoaded = (String) SerializationUtils.deserialize(dataOut); System.out.println(hasLoaded); } finally { tester.tearDown(); } } }

它看起来像正确的东西使它到数据库:

cqlsh:flight_cache> select * from test_serialization.test_table; id | data --------+-------------------------------------------- 123 | 0x010203 toSave | 0xaced000574000d48656c6c6f2c20776f726c6421 cqlsh:flight_cache>

因此,阅读时,而不是写,二进制数据看起来像一个错误。 谁能给我任何指针,以我在做什么错?

--------------解决方案-------------

问题是几乎可以肯定,因为ByteBuffer.array()返回的数组是全力支持数组,但该数据可能只包含其中的一部分之内。

正在返回的有效数据在ByteBuffer.arrayOffset()开始,是一个长度为ByteBuffer.remaining的()。 为了得到只包含有效数据readFromTable使用此代码的字节数组:

byte[] result = new byte[data.remaining()];
data.get(result);

那么你的数据是结果,你可以返回。

既然你已经使用DataStax Java驱动程序,也有在一个工具类com.datastax.driver.core.utils您可以使用这样的:

byte[] result = Bytes.getArray(data)

分类:java的 时间:2015-03-14 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.698 (s). 10 q(s)