美文网首页
ByteBuffer和String类型转换

ByteBuffer和String类型转换

作者: DizzyDwarf | 来源:发表于2019-03-07 23:01 被阅读0次

最近在学Java的NIO,自己写代码实践的时候数据需要在String和ByteBuffer之间互相转换,发现还挺别扭的,于是上网查了下。

网上常见做法

String转ByteBuffer

ByteBuffer buffer = ByteBuffer.wrap("Content of the String".getBytes("utf-8"));

ByteBuffer转String

buffer是ByteBuffer类型的对象

Charset charset = Charset.forName("utf-8");
CharBuffer charBuffer = charset.decode(buffer);
String s = charBuffer.toString();

也可以用

Charset charset = Charset.forName("utf-8");
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buffer);
String s = charBuffer.toString();

两者的区别在于对非法输入的处理

说明

第一次用ByteBuffer.wrap的时候惯性思维在后面加上了flip调用,结果发现数据并没有写入Channel。通过查源代码发现wrap方法返回的是一个HeapByteBuffer的对象,而HeapByteBuffer调用父类的构造函数传入的pos参数是off,也就是调用wrap方法的第二个参数,默认是0。

public static ByteBuffer wrap(byte[] array,
                                int offset, int length)
{
    try {
        return new HeapByteBuffer(array, offset, length);
    } catch (IllegalArgumentException x) {
        throw new IndexOutOfBoundsException();
    }
}
HeapByteBuffer(byte[] buf, int off, int len) { // package-private
    super(-1, off, off + len, buf.length, buf, 0);
}
ByteBuffer(int mark, int pos, int lim, int cap,   // package-private
            byte[] hb, int offset)
{
    super(mark, pos, lim, cap);
    this.hb = hb;
    this.offset = offset;
}

flip方法的逻辑是

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

因此调用flip方法后limit = position = 0,导致不能从Buffer中读取数据。

我的做法

顺便说一下我自己的转换方式

String转ByteBuffer

ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("Content of the String".getBytes("utf-8"));
buffer.flip();

这种做法的缺点在于ByteBuffer大小固定,而且需要自己调用flip切换到读模式。

ByteBuffer转String

buffer是ByteBuffer类型的对象

new String(buffer.array(), buffer.position(), buffer.limit(), "utf-8");

相关文章

网友评论

      本文标题:ByteBuffer和String类型转换

      本文链接:https://www.haomeiwen.com/subject/ummkpqtx.html