Text中有length和bytes,length是获取字符转换为字节的长度,但是bytes的长度可能要大于length的长度
Text t=new Text("hadoop");
t.set("pig");
System.out.println(t.getLength()+":"+t.getBytes().length);
结果 3:3
Text t2=new Text("hadoop");
t2.set(new Text("pig"));
System.out.println(t2.getLength()+":"+t2.getBytes().length);
结果3:6
把Text对象序列化表示为第一个字节是Text的字符串中的字节数既length,后面跟UTF-8字节本身,例如:
public byte[] seralizle(Writable writable) throws IOException
{
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
DataOutputStream dout=new DataOutputStream(outputStream);
writable.write(dout);
dout.close();
return outputStream.toByteArray();
}
public static void main(String[] args) throws Exception {
byte[] b=stest.seralizle(new Text("haoop"));
System.out.println(StringUtils.byteToHexString(b));
}
结果:066861646f6f70,第一个字节06表示这个text对象有6个字节组成的字符串
上面的代码调用Text类中write方法:
public void write(DataOutput out) throws IOException {
WritableUtils.writeVInt(out, length);//写入length即text对象的长度
【调用的WritableUtils中write方法其实是调用了writeVLong
public static void writeVLong(DataOutput stream, long i) throws IOException {
if (i >= -112 && i <= 127) {
stream.writeByte((byte)i);
return;
}
//。。。后面的就不要了,后面的是针对Int,VInt和Long等类型的写入;
】
out.write(bytes, 0, length);//接着是把字节写入流中,至于是从0开始,可以看调用dataoutputstream调用的代码,dataoutputstream就是装饰模式中的装饰器,所以还是调用的ByteArrayOutputStream的write方法
【ByteArrayOutputStream类中
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
}
ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
count += len;//count是记录当前写入buf中的长度,count是1
}
】
}
t.set("pig");
System.out.println(t.getLength()+":"+t.getBytes().length);
t2.set(new Text("pig"));
System.out.println(t2.getLength()+":"+t2.getBytes().length);
{
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
DataOutputStream dout=new DataOutputStream(outputStream);
writable.write(dout);
dout.close();
return outputStream.toByteArray();
}
public static void main(String[] args) throws Exception {
byte[] b=stest.seralizle(new Text("haoop"));
System.out.println(StringUtils.byteToHexString(b));
}
WritableUtils.writeVInt(out, length);//写入length即text对象的长度
【调用的WritableUtils中write方法其实是调用了writeVLong
public static void writeVLong(DataOutput stream, long i) throws IOException {
if (i >= -112 && i <= 127) {
stream.writeByte((byte)i);
return;
}
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
}
ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
count += len;//count是记录当前写入buf中的长度,count是1
}
】
}