我已经阅读了关于使用HBase存储字符串数组的答案(How to store complex objects into hadoop Hbase?)。
据说它使用ArrayWritable
类来序列化数组。使用WritableUtils.toByteArray(Writable ... writable)
,我将获得byte[]
,我可以将其存储在HBase中。
当我现在尝试再次检索行时,我得到一个byte[]
,我以某种方式将其转换回ArrayWritable
。
但我找不到办法做到这一点。也许你知道答案,或者我是否在根本错误地序列化我的String[]
?
答案 0 :(得分:5)
您可以应用以下方法取回ArrayWritable
(取自我之前的回答,请参阅here)。
public static <T extends Writable> T asWritable(byte[] bytes, Class<T> clazz)
throws IOException {
T result = null;
DataInputStream dataIn = null;
try {
result = clazz.newInstance();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
dataIn = new DataInputStream(in);
result.readFields(dataIn);
}
catch (InstantiationException e) {
// should not happen
assert false;
}
catch (IllegalAccessException e) {
// should not happen
assert false;
}
finally {
IOUtils.closeQuietly(dataIn);
}
return result;
}
此方法只是根据提供的类类型标记将字节数组反序列化为正确的对象类型 例如: 假设你有一个自定义的ArrayWritable:
public class TextArrayWritable extends ArrayWritable {
public TextArrayWritable() {
super(Text.class);
}
}
现在你发出一个HBase get:
...
Get get = new Get(row);
Result result = htable.get(get);
byte[] value = result.getValue(family, qualifier);
TextArrayWritable tawReturned = asWritable(value, TextArrayWritable.class);
Text[] texts = (Text[]) tawReturned.toArray();
for (Text t : texts) {
System.out.print(t + " ");
}
...
注意:
您可能已经在WritableUtils中找到了readCompressedStringArray()和writeCompressedStringArray()方法
如果您有自己的String数组支持的Writable类,这似乎是合适的。
在使用它们之前,我会警告你,这些可能会导致严重的性能损失
由gzip压缩/解压缩引起的开销。